Documentation
¶
Overview ¶
Package testutil provides testing utilities for pgwatch tests.
This package contains mock implementations, test setup helpers, and constants used across test files. It should only be imported by test files (*_test.go) and will not be included in production binaries.
The package includes:
- Mock gRPC receivers for testing sink implementations
- PostgreSQL container setup for integration tests
- gRPC server setup with TLS support for testing
- Test certificates and keys for TLS testing
Index ¶
- Constants
- Variables
- func AuthInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, ...) (any, error)
- func BlackholeListener(t *testing.T) (string, func())
- func LoadServerTLSCredentials() (credentials.TransportCredentials, error)
- func NewFakeExporter(t *testing.T, body string) *httptest.Server
- func SetupEtcdContainer() (*etcd.EtcdContainer, func(), error)
- func SetupPostgresContainer() (*postgres.PostgresContainer, func(), error)
- func SetupPostgresContainerWithConfig(configPath string) (*postgres.PostgresContainer, func(), error)
- func SetupPostgresContainerWithInitScripts(scripts ...string) (*postgres.PostgresContainer, func(), error)
- func SetupRPCServers() (func(), error)
- type BlockingBatchResults
- type BlockingPool
- func (BlockingPool) Acquire(ctx context.Context) (*pgxpool.Conn, error)
- func (BlockingPool) Close()
- func (BlockingPool) Exec(ctx context.Context, _ string, _ ...any) (pgconn.CommandTag, error)
- func (BlockingPool) Ping(ctx context.Context) error
- func (BlockingPool) Query(ctx context.Context, _ string, _ ...any) (pgx.Rows, error)
- func (BlockingPool) QueryRow(ctx context.Context, _ string, _ ...any) pgx.Row
- func (BlockingPool) SendBatch(ctx context.Context, _ *pgx.Batch) pgx.BatchResults
- type MockMetricsReaderWriter
- func (m *MockMetricsReaderWriter) CreateMetric(name string, metric metrics.Metric) error
- func (m *MockMetricsReaderWriter) CreatePreset(name string, preset metrics.Preset) error
- func (m *MockMetricsReaderWriter) DeleteMetric(name string) error
- func (m *MockMetricsReaderWriter) DeletePreset(name string) error
- func (m *MockMetricsReaderWriter) GetMetrics() (*metrics.Metrics, error)
- func (m *MockMetricsReaderWriter) UpdateMetric(name string, metric metrics.Metric) error
- func (m *MockMetricsReaderWriter) UpdatePreset(name string, preset metrics.Preset) error
- func (m *MockMetricsReaderWriter) WriteMetrics(metricDefs *metrics.Metrics) error
- type MockSourcesReaderWriter
- func (m *MockSourcesReaderWriter) CreateSource(md sources.Source) error
- func (m *MockSourcesReaderWriter) DeleteSource(name string) error
- func (m *MockSourcesReaderWriter) GetSources() (sources.Sources, error)
- func (m *MockSourcesReaderWriter) UpdateSource(md sources.Source) error
- func (m *MockSourcesReaderWriter) WriteSources(srcs sources.Sources) error
- type Receiver
- func (receiver *Receiver) DefineMetrics(_ context.Context, metricsStruct *structpb.Struct) (*pb.Reply, error)
- func (receiver *Receiver) SyncMetric(_ context.Context, syncReq *pb.SyncReq) (*pb.Reply, error)
- func (receiver *Receiver) UpdateMeasurements(_ context.Context, msg *pb.MeasurementEnvelope) (*pb.Reply, error)
- type SafeBuffer
Constants ¶
const EtcdImage = "gcr.io/etcd-development/etcd:" + EtcdVersion
const EtcdVersion = "v3.5.14"
const MockDatabase = "mydatabase"
const PlainConnStr = "grpc://localhost:6060"
const PlainServerAddress = "localhost:6060"
const PostgresImage = "docker.io/postgres:19beta2-alpine"
const TLSServerAddress = "localhost:5050"
Variables ¶
var CA = `` /* 1187-byte string literal not displayed */
var CAFile = "ca.crt"
var Cert = []byte(`-----BEGIN CERTIFICATE-----
MIIDZTCCAk2gAwIBAgIQeTQ+4M7xwydf7MvrDnDdsTANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQDDAdwZ3dhdGNoMB4XDTI1MDYxMTA1MjUxOFoXDTI3MDkxNDA1MjUx
OFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA69Ja9K4ZHoIdBK+34YE1+0a/sB7YKZJb3+gYFahvszS37Oa6h/0+
d9TCY58bMpPQSQQdvhG/s1H6Yc4BWTfH/ssRmDhKciMmdfMj/lr8TytglIUPPSzb
PKy2t9idpk30PwiV1UlijjlFZxoxcO3Aia8mmrDJzkoHsQL96PhDT25YRinnflg8
vVthasVqGIHNJIXORyz5lgkBW3NeeZPEUSxbvmo63AB1lFJZMz4xlpdN/LVsEOwg
FrrYzb4mpGkAcTenkOfU4W7m7bxpsusW2JDm2O8bsx+v3cazOqJpCLMHP3Vqnzcl
loYmeQauBep6H0wspid0YzMVza75pDx7rQIDAQABo4G0MIGxMAkGA1UdEwQCMAAw
HQYDVR0OBBYEFFcDjPaZMelQIueauIRfo4L4wMehME0GA1UdIwRGMESAFChibOzl
yDXdli+l9pnh/dHiDaCUoRakFDASMRAwDgYDVQQDDAdwZ3dhdGNoghR4Q1CVAVUf
mHsezMUkstaj4oJDBDATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAw
FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCM6tYNxoP2
Gbp3aAPjoA3+U1gWHPHXOOgyhaQw4jJ7xK1MUlrFgSG6cJgO7IRSCIZp7GDZmIjo
+PqWRgMNK2pFCUCqjrAV6NwMjApLzDdSza9xKb3nWXMKnV6j3tNUFUCS68CHAM7Q
E1iuepjIy2VReFfjJoPuhp9OQBWobTo3H9F74Sj+Guu0lDcHWbwn5Y92pnKk0vOh
v1AJ6vwdMpd6DAPlwmY3OcZI2FGYyoPP2CnzHIGP5RoVFp1zkJzoFvnOHnsRMByz
HpGKqYFQVJSAOMCtL2OMiP8MxtiCsdz6j/e3/VOUQuYoM6fXFhZO64xekZdlh/ZR
glsaMXQPWvHX
-----END CERTIFICATE-----`)
var PrivateKey = []byte(`-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDr0lr0rhkegh0E
r7fhgTX7Rr+wHtgpklvf6BgVqG+zNLfs5rqH/T531MJjnxsyk9BJBB2+Eb+zUfph
zgFZN8f+yxGYOEpyIyZ18yP+WvxPK2CUhQ89LNs8rLa32J2mTfQ/CJXVSWKOOUVn
GjFw7cCJryaasMnOSgexAv3o+ENPblhGKed+WDy9W2FqxWoYgc0khc5HLPmWCQFb
c155k8RRLFu+ajrcAHWUUlkzPjGWl038tWwQ7CAWutjNviakaQBxN6eQ59Thbubt
vGmy6xbYkObY7xuzH6/dxrM6omkIswc/dWqfNyWWhiZ5Bq4F6nofTCymJ3RjMxXN
rvmkPHutAgMBAAECggEAAc8djQJ35VzEqbhKXhO+bQTMLCb0bA84HrXaV3IxFywY
nBviAvCNpeAvNJHwJLlvD9xU+RQMRy0iEVWB+6P6qAj5Q9Rst8buwNliZY1foaDY
zxLdPNAnB2ZgyXTDMtcmwEQJ2DbFp4cnceTIy8+7GiNKlcW06pz1RaWa+opLA+U2
STIxvTEAvqsyE/0KHbeEltwZxeZ83BsX8vhpyrCVvniFJnIMvyYG7iTzLWuTK98Z
R3Baqim8CdWbh2W0OOfphAVlTjG6c0r6FqJIqsds9wf2FfuhgUcNQUXke+uuWbPQ
36RsytymUgqye3DkxrC4dEi27S3cjRh5wK53gqET+QKBgQD8zM5wiindvDRSx+66
ppbl6RJQcL7uv1os9TeNvfqwnhC75y2k4+2s8kiG2ik7aJiRg4dkj3rVJ4S6wQ67
sjRVo5z68J1twP6PqvpJyx/G5Fmy8HPJUmy9FM1AdnYCWGX3bh3qNTkxEVn78yFZ
zfn9CczDAmGErAXPRRDNQQy8ZQKBgQDuzofs5EXTpqw25XveCJKHT3fAis7pkNGu
jwopiR9peKuJ9nNarHH2wWpHRn6zgHmhmAu7oEzo4OEmk4Elo5ffqqRPZZaU8aEo
Ow7cRvedoP/EjJaR8m2uQnh9bWXuEVibfKmkrPswYYUCWmwoALFmzd6Gl0dIdyGk
JXeA/jFZqQKBgQDhFbn5mgsM0rYDvuBgcFOLAaq81KYsDVRNE0kTe0PqXdKoe324
gvjsNA0/hJ+Rtd+iMGosr1O+1iDn510m4dSXK8Zp6DNDtcLySFnxulngzRDQsidl
6W3ILO1TqCYKkIq5c+JO1nTFq51jJ2dafntHQaJ/P290oXXKxsPe/TxJwQKBgD6g
dS8f8lv+Mt22sxRYhSztH0ekX30LWKIBqzWXW2CKn9nvgvL9lGmU8a09hI7Im51Q
RYtwD5tnFkTKnCzlyTeEBdE4oBPxhkUJr+z+w4NYLJs8D2S5AiCYGAc0wG19qRIl
0Et6femDOaGTWxfmjp+aT8hWNgCAFZd5p+xxPTn5AoGBAIeUbCRTe0KcVaKw/Lcj
KHjTih9x9d3f2EbnYbziBZz6fZfWdDIBfA6CbIHil21hNvjDm9Yci5b6FgtUzScb
j3vPa99sMGc2xie07Cd7LTvZeWIVXeW1Dxzex89CqoJzmONrco1ZKQ+xXbPoZCBj
VwAI/SWm7NlxgF6Sr5CIo2KR
-----END PRIVATE KEY-----`)
var TLSConnStr = fmt.Sprintf("grpc://localhost:5050?sslrootca=%s", CAFile)
var TestContext = log.WithLogger(context.Background(), log.NewNoopLogger())
Functions ¶
func AuthInterceptor ¶
func AuthInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error)
func BlackholeListener ¶
BlackholeListener starts a TCP listener that accepts connections but never reads, writes, or closes them. Each accepted connection runs in its own goroutine that blocks until the listener is shut down.
This simulates a half-open TCP connection: the client sees an established TCP session, but no application-layer response ever arrives. The kernel keeps the connection open until the local read deadline (if any) fires or the peer gives up. Callers pair this with a context-bound round-trip to convert such stalls into bounded client-side failures.
The address is registered for cleanup via t.Cleanup, so a single BlackholeListener(t) call is leak-free under normal test runs. The returned close func is idempotent and may also be invoked explicitly by the test for early teardown.
Concurrency: the accept loop and any number of accepted connections run concurrently. Accepted goroutines block until ctx is cancelled; the close func waits for them via wg.Wait before returning.
func LoadServerTLSCredentials ¶
func LoadServerTLSCredentials() (credentials.TransportCredentials, error)
func NewFakeExporter ¶
NewFakeExporter starts an httptest.Server that responds to any request with the provided Prometheus exposition-format body and Content-Type "text/plain; version=0.0.4". The server is automatically closed when the test finishes via t.Cleanup.
func SetupEtcdContainer ¶
func SetupEtcdContainer() (*etcd.EtcdContainer, func(), error)
func SetupPostgresContainer ¶
func SetupPostgresContainer() (*postgres.PostgresContainer, func(), error)
func SetupPostgresContainerWithConfig ¶
func SetupPostgresContainerWithConfig(configPath string) (*postgres.PostgresContainer, func(), error)
Creates a PostgreSQL container with CSV logging enabled. This is useful for testing log parsing functionality with server_log_event_counts metric.
func SetupPostgresContainerWithInitScripts ¶
func SetupPostgresContainerWithInitScripts(scripts ...string) (*postgres.PostgresContainer, func(), error)
func SetupRPCServers ¶
func SetupRPCServers() (func(), error)
Types ¶
type BlockingBatchResults ¶
type BlockingBatchResults struct {
// contains filtered or unexported fields
}
BlockingBatchResults makes the first Query call honor ctx cancellation.
func (*BlockingBatchResults) Close ¶
func (b *BlockingBatchResults) Close() error
func (*BlockingBatchResults) Err ¶
func (b *BlockingBatchResults) Err() error
func (*BlockingBatchResults) Exec ¶
func (b *BlockingBatchResults) Exec() (pgconn.CommandTag, error)
Exec blocks until ctx.Done() and returns ctx.Err().
func (*BlockingBatchResults) Query ¶
func (b *BlockingBatchResults) Query() (pgx.Rows, error)
Query blocks until ctx.Done() and returns ctx.Err().
func (*BlockingBatchResults) QueryRow ¶
func (b *BlockingBatchResults) QueryRow() pgx.Row
QueryRow blocks until ctx.Done() and returns a Row whose Scan returns ctx.Err().
type BlockingPool ¶
type BlockingPool struct {
db.PgxPoolIface
}
BlockingPool is a wedged PgxPoolIface used by fault-injection tests.
It embeds db.PgxPoolIface as a nil interface so the type satisfies db.PgxPoolIface; only the methods overridden below are usable. Any direct call to a non-overridden method panics (nil interface call).
Ping, Query, SendBatch, and Acquire all block until the supplied context is cancelled, then return ctx.Err(). This simulates a pool whose connections are stuck on the wire — the failure mode that client-side deadlines must convert into bounded failures.
func (BlockingPool) Close ¶
func (BlockingPool) Close()
Close is a no-op so the pool can be embedded without panicking.
func (BlockingPool) Exec ¶
func (BlockingPool) Exec(ctx context.Context, _ string, _ ...any) (pgconn.CommandTag, error)
Exec blocks until ctx.Done() and returns ctx.Err().
func (BlockingPool) Ping ¶
func (BlockingPool) Ping(ctx context.Context) error
Ping blocks until ctx.Done() and returns ctx.Err().
func (BlockingPool) QueryRow ¶
QueryRow blocks until ctx.Done() and returns a row whose Scan returns ctx.Err().
func (BlockingPool) SendBatch ¶
func (BlockingPool) SendBatch(ctx context.Context, _ *pgx.Batch) pgx.BatchResults
first Query call returns ctx.Err(). SendBatch blocks until ctx.Done() and returns a BatchResults whose first Query call returns ctx.Err().
type MockMetricsReaderWriter ¶
type MockMetricsReaderWriter struct {
GetMetricsFunc func() (*metrics.Metrics, error)
UpdateMetricFunc func(name string, m metrics.Metric) error
CreateMetricFunc func(name string, m metrics.Metric) error
DeleteMetricFunc func(name string) error
DeletePresetFunc func(name string) error
UpdatePresetFunc func(name string, preset metrics.Preset) error
CreatePresetFunc func(name string, preset metrics.Preset) error
WriteMetricsFunc func(metricDefs *metrics.Metrics) error
}
MockMetricsReaderWriter implements MetricsReaderWriter interface
func (*MockMetricsReaderWriter) CreateMetric ¶
func (m *MockMetricsReaderWriter) CreateMetric(name string, metric metrics.Metric) error
func (*MockMetricsReaderWriter) CreatePreset ¶
func (m *MockMetricsReaderWriter) CreatePreset(name string, preset metrics.Preset) error
func (*MockMetricsReaderWriter) DeleteMetric ¶
func (m *MockMetricsReaderWriter) DeleteMetric(name string) error
func (*MockMetricsReaderWriter) DeletePreset ¶
func (m *MockMetricsReaderWriter) DeletePreset(name string) error
func (*MockMetricsReaderWriter) GetMetrics ¶
func (m *MockMetricsReaderWriter) GetMetrics() (*metrics.Metrics, error)
func (*MockMetricsReaderWriter) UpdateMetric ¶
func (m *MockMetricsReaderWriter) UpdateMetric(name string, metric metrics.Metric) error
func (*MockMetricsReaderWriter) UpdatePreset ¶
func (m *MockMetricsReaderWriter) UpdatePreset(name string, preset metrics.Preset) error
func (*MockMetricsReaderWriter) WriteMetrics ¶
func (m *MockMetricsReaderWriter) WriteMetrics(metricDefs *metrics.Metrics) error
type MockSourcesReaderWriter ¶
type MockSourcesReaderWriter struct {
GetSourcesFunc func() (sources.Sources, error)
UpdateSourceFunc func(md sources.Source) error
CreateSourceFunc func(md sources.Source) error
DeleteSourceFunc func(name string) error
WriteSourcesFunc func(sources.Sources) error
}
MockSourcesReaderWriter implements SourcesReaderWriter interface
func (*MockSourcesReaderWriter) CreateSource ¶
func (m *MockSourcesReaderWriter) CreateSource(md sources.Source) error
func (*MockSourcesReaderWriter) DeleteSource ¶
func (m *MockSourcesReaderWriter) DeleteSource(name string) error
func (*MockSourcesReaderWriter) GetSources ¶
func (m *MockSourcesReaderWriter) GetSources() (sources.Sources, error)
func (*MockSourcesReaderWriter) UpdateSource ¶
func (m *MockSourcesReaderWriter) UpdateSource(md sources.Source) error
func (*MockSourcesReaderWriter) WriteSources ¶
func (m *MockSourcesReaderWriter) WriteSources(srcs sources.Sources) error
type Receiver ¶
type Receiver struct {
pb.UnimplementedReceiverServer
}
Receiver implements the ReceiverServer interface for testing purposes
func (*Receiver) DefineMetrics ¶
func (*Receiver) SyncMetric ¶
func (*Receiver) UpdateMeasurements ¶
type SafeBuffer ¶
type SafeBuffer struct {
// contains filtered or unexported fields
}
SafeBuffer is a goroutine-safe string buffer that satisfies io.Writer. Use String() to read the accumulated output.
func NewTestLogger ¶
NewTestLogger creates a capturing logger at the given level, injects it into a context derived from t.Context(), and returns both the context and the output buffer. Use the buffer in assertions to verify log output:
ctx, out := testutil.NewTestLogger(t, logrus.WarnLevel) doSomething(ctx) assert.Contains(t, out.String(), "expected warning")
func (*SafeBuffer) String ¶
func (b *SafeBuffer) String() string
String returns a snapshot of the accumulated log output.