apptest

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 24, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

README

App Integration Tests

The apptest package contains the integration tests for the VictoriaLogs applications (such as victoria-traces).

An integration test aims at verifying the behavior of an application as a whole, as apposed to a unit test that verifies the behavior of a building block of an application.

To achieve that an integration test starts an application in a separate process and then issues HTTP requests to it and verifies the responses, examines the metrics the app exposes and/or files it creates, etc.

Note that an object of testing may be not just a single app, but several apps working together. A good example is VictoriaMetrics cluster. An integration test may reproduce an arbitrary cluster configuration and verify how the components work together as a system.

The package provides a collection of helpers to start applications and make queries to them:

  • app.go - contains the generic code for staring an application and should not be used by integration tests directly.
  • {vtsingle,etc}.go - build on top of app.go and provide the code for staring a specific application.
  • client.go - provides helper functions for sending HTTP requests to applications.

The integration tests themselves reside in tests/*_test.go files. Apart from having the _test suffix, there are no strict rules of how to name a file, but the name should reflect the prevailing purpose of the tests located in that file. For example, sharding_test.go aims at testing data sharding.

Since integration tests start applications in a separate process, they require the application binary files to be built and put into the bin directory. The build rule used for running integration tests, make integration-test, accounts for that, it builds all application binaries before running the tests. But if you want to run the tests without make, i.e. by executing go test ./app/apptest, you will need to build the binaries first (for example, by executing make all).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetHTTP2Client added in v0.5.0

func GetHTTP2Client() *http.Client

Types

type AssertOptions

type AssertOptions struct {
	Msg        string
	Got        func() any
	Want       any
	CmpOpts    []cmp.Option
	DoNotRetry bool
	Retries    int
	Period     time.Duration
	FailNow    bool
}

AssertOptions hold the assertion params, such as got and wanted values as well as the message that should be included into the assertion error message in case of failure.

In VictoriaMetrics (especially the cluster version) the inserted data does not become visible for querying right away. Therefore, the first comparisons may fail. AssertOptions allow to configure how many times the actual result must be retrieved and compared with the expected one and for long to wait between the retries. If these two params (`Retries` and `Period`) are not set, the default values will be used.

If it is known that the data is available, then the retry functionality can be disabled by setting the `DoNotRetry` field.

AssertOptions are used by the TestCase.Assert() method, and this method uses cmp.Diff() from go-cmp package for comparing got and wanted values. AssertOptions, therefore, allows to pass cmp.Options to cmp.Diff() via `CmpOpts` field.

Finally the `FailNow` field controls whether the assertion should fail using `testing.T.Errorf()` or `testing.T.Fatalf()`.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is used for interacting with the apps over the network.

func NewClient

func NewClient() *Client

NewClient creates a new client.

func (*Client) CloseConnections

func (c *Client) CloseConnections()

CloseConnections closes client connections.

func (*Client) Delete

func (c *Client) Delete(t *testing.T, url string) (string, int)

Delete sends a HTTP DELETE request and returns the response body and status code to the caller.

func (*Client) Get

func (c *Client) Get(t *testing.T, url string) (string, int)

Get sends a HTTP GET request, returns the response body and status code to the caller.

func (*Client) Post

func (c *Client) Post(t *testing.T, url, contentType string, data []byte) (string, int)

Post sends a HTTP POST request, returns the response body and status code to the caller.

func (*Client) PostForm

func (c *Client) PostForm(t *testing.T, url string, data url.Values) (string, int)

PostForm sends a HTTP POST request containing the POST-form data, returns the response body and status code to the caller.

func (*Client) Write

func (c *Client) Write(t *testing.T, address string, data []string)

type DependenciesResponseData added in v0.4.0

type DependenciesResponseData struct {
	Parent    string `json:"parent"`
	Child     string `json:"child"`
	CallCount int    `json:"callCount"`
}

type JaegerAPIDependenciesResponse added in v0.4.0

type JaegerAPIDependenciesResponse struct {
	Data []DependenciesResponseData `json:"data"`
	JaegerResponse
}

func NewJaegerAPIDependenciesResponse added in v0.4.0

func NewJaegerAPIDependenciesResponse(t *testing.T, s string) *JaegerAPIDependenciesResponse

NewJaegerAPIDependenciesResponse is a test helper function that creates a new instance of JaegerAPIDependenciesResponse by unmarshalling a json string.

type JaegerAPIOperationsResponse

type JaegerAPIOperationsResponse struct {
	Data []string `json:"data"`
	JaegerResponse
}

JaegerAPIOperationsResponse is an in-memory representation of the /select/jaeger/services/<service_name>/operations response.

func NewJaegerAPIOperationsResponse

func NewJaegerAPIOperationsResponse(t *testing.T, s string) *JaegerAPIOperationsResponse

NewJaegerAPIOperationsResponse is a test helper function that creates a new instance of JaegerAPIOperationsResponse by unmarshalling a json string.

type JaegerAPIServicesResponse

type JaegerAPIServicesResponse struct {
	Data []string `json:"data"`
	JaegerResponse
}

JaegerAPIServicesResponse is an in-memory representation of the /select/jaeger/services response.

func NewJaegerAPIServicesResponse

func NewJaegerAPIServicesResponse(t *testing.T, s string) *JaegerAPIServicesResponse

NewJaegerAPIServicesResponse is a test helper function that creates a new instance of JaegerAPIServicesResponse by unmarshalling a json string.

type JaegerAPITraceResponse

type JaegerAPITraceResponse struct {
	Data []TracesResponseData `json:"data"`
	JaegerResponse
}

JaegerAPITraceResponse is an in-memory representation of the /select/jaeger/traces/<trace_id> response.

func NewJaegerAPITraceResponse

func NewJaegerAPITraceResponse(t *testing.T, s string) *JaegerAPITraceResponse

NewJaegerAPITraceResponse is a test helper function that creates a new instance of JaegerAPITraceResponse by unmarshalling a json string.

type JaegerAPITracesResponse

type JaegerAPITracesResponse struct {
	Data []TracesResponseData `json:"data"`
	JaegerResponse
}

JaegerAPITracesResponse is an in-memory representation of the /select/jaeger/traces response.

func NewJaegerAPITracesResponse

func NewJaegerAPITracesResponse(t *testing.T, s string) *JaegerAPITracesResponse

NewJaegerAPITracesResponse is a test helper function that creates a new instance of JaegerAPITracesResponse by unmarshalling a json string.

type JaegerDependenciesParam added in v0.4.0

type JaegerDependenciesParam struct {
	query.ServiceGraphQueryParameters
}

JaegerDependenciesParam is a helper structure for implementing extra helper functions of `query.ServiceGraphQueryParameters`.

type JaegerQuerier

type JaegerQuerier interface {
	JaegerAPIServices(t *testing.T, opts QueryOpts) *JaegerAPIServicesResponse
	JaegerAPIOperations(t *testing.T, serviceName string, opts QueryOpts) *JaegerAPIOperationsResponse
	JaegerAPITraces(t *testing.T, params JaegerQueryParam, opts QueryOpts) *JaegerAPITracesResponse
	JaegerAPITrace(t *testing.T, traceID string, opts QueryOpts) *JaegerAPITraceResponse
	JaegerAPIDependencies(t *testing.T, params JaegerDependenciesParam, opts QueryOpts) *JaegerAPIDependenciesResponse
}

JaegerQuerier contains methods available to Jaeger HTTP API for Querying.

type JaegerQueryParam

type JaegerQueryParam struct {
	query.TraceQueryParam
}

JaegerQueryParam is a helper structure for implementing extra helper functions of `query.TraceQueryParam`.

type JaegerResponse

type JaegerResponse struct {
	Errors interface{} `json:"errors"`
	Limit  int         `json:"limit"`
	Offset int         `json:"offset"`
	Total  int         `json:"total"`
}

JaegerResponse contains the common fields shared by all responses of Jaeger query APIs.

type Log

type Log struct {
	Timestamp int64 `json:"timestamp"`
	Fields    []Tag `json:"fields"`
}

Log is the structure for Jaeger Log.

type LogsQLQuerier added in v0.6.0

type LogsQLQuerier interface {
	LogsQLQuery(t *testing.T, LogsQL string, ops QueryOpts) *LogsQLQueryResponse
}

type LogsQLQueryResponse added in v0.6.0

type LogsQLQueryResponse struct {
	LogLines []string
}

LogsQLQueryResponse is an in-memory representation of the /select/logsql/query response.

func NewLogsQLQueryResponse added in v0.6.0

func NewLogsQLQueryResponse(t *testing.T, s string) *LogsQLQueryResponse

NewLogsQLQueryResponse is a test helper function that creates a new instance of LogsQLQueryResponse by unmarshalling a json string.

type OTLPTracesWriter

type OTLPTracesWriter interface {
	OTLPHTTPExportTraces(t *testing.T, request *otelpb.ExportTraceServiceRequest, opts QueryOpts)
	OTLPgRPCExportTraces(t *testing.T, request *otelpb.ExportTraceServiceRequest, opts QueryOpts)

	// low level methods only for tests with raw data. avoid using them unless the methods above can't fulfill the requirement.
	OTLPHTTPExportRawTraces(t *testing.T, data []byte, opts QueryOpts)
}

OTLPTracesWriter contains methods for writing OTLP trace data.

type Process

type Process struct {
	ServiceName string `json:"serviceName"`
	Tags        []Tag  `json:"tags"`
}

Process is the structure for Jaeger Process.

type QueryOpts

type QueryOpts struct {
	Timeout       string
	Start         string
	End           string
	Time          string
	Step          string
	ExtraFilters  []string
	ExtraLabels   []string
	MaxLookback   string
	LatencyOffset string
	Format        string
	Limit         string

	// for ingestion
	HTTPHeaders map[string]string
}

QueryOpts contains various params used for querying or ingesting data

type Reference

type Reference struct {
	RefType string `json:"refType"`
	SpanID  string `json:"spanID"`
	TraceID string `json:"traceID"`
}

Reference is the structure for Jaeger Reference.

type ServesMetrics

type ServesMetrics struct {
	// contains filtered or unexported fields
}

ServesMetrics is used to retrieve the app's metrics.

This type is expected to be embedded by the apps that serve metrics.

func (*ServesMetrics) GetIntMetric

func (app *ServesMetrics) GetIntMetric(t *testing.T, metricName string) int

GetIntMetric retrieves the value of a metric served by an app at /metrics URL. The value is then converted to int.

func (*ServesMetrics) GetMetric

func (app *ServesMetrics) GetMetric(t *testing.T, metricName string) float64

GetMetric retrieves the value of a metric served by an app at /metrics URL.

func (*ServesMetrics) GetMetricsByPrefix

func (app *ServesMetrics) GetMetricsByPrefix(t *testing.T, prefix string) []float64

GetMetricsByPrefix retrieves the values of all metrics that start with given prefix.

func (*ServesMetrics) TryGetMetric added in v0.4.0

func (app *ServesMetrics) TryGetMetric(t *testing.T, metricName string) (float64, error)

type Span

type Span struct {
	Duration      int         `json:"duration"`
	Logs          []Log       `json:"logs"`
	OperationName string      `json:"operationName"`
	ProcessID     string      `json:"processID"`
	References    []Reference `json:"references"`
	SpanID        string      `json:"spanID"`
	StartTime     int64       `json:"startTime"`
	Tags          []Tag       `json:"tags"`
	TraceID       string      `json:"traceID"`
	Warnings      interface{} `json:"warnings"`
}

Span is the structure for Jaeger Span.

type Stopper

type Stopper interface {
	Stop()
}

Stopper is an interface of objects that needs to be stopped via Stop() call

type StorageFlusher

type StorageFlusher interface {
	ForceFlush(t *testing.T)
}

StorageFlusher defines a method that forces the flushing of data inserted into the storage, so it becomes available for searching immediately.

type StorageMerger

type StorageMerger interface {
	ForceMerge(t *testing.T)
}

StorageMerger defines a method that forces the merging of data inserted into the storage.

type Tag

type Tag struct {
	Key   string `json:"key"`
	Type  string `json:"type"`
	Value string `json:"value"`
}

Tag is the structure for Jaeger tag.

type TestCase

type TestCase struct {
	// contains filtered or unexported fields
}

TestCase holds the state and defines clean-up procedure common for all test cases.

func NewTestCase

func NewTestCase(t *testing.T) *TestCase

NewTestCase creates a new test case.

func (*TestCase) Assert

func (tc *TestCase) Assert(opts *AssertOptions)

Assert compares the actual result with the expected one possibly multiple times in order to account for the fact that the inserted data does not become available for querying right away (especially in cluster version of VictoriaMetrics).

func (*TestCase) Client

func (tc *TestCase) Client() *Client

Client returns an instance of the client that can be used for interacting with the app(s) under test.

func (*TestCase) Dir

func (tc *TestCase) Dir() string

Dir returns the directory name that should be used by as the -storageDataDir.

func (*TestCase) MustStartDefaultVtsingle

func (tc *TestCase) MustStartDefaultVtsingle() *Vtsingle

MustStartDefaultVtsingle is a test helper function that starts an instance of vtsingle with defaults suitable for most tests.

func (*TestCase) MustStartVtsingle

func (tc *TestCase) MustStartVtsingle(instance string, flags []string) *Vtsingle

MustStartVtsingle is a test helper function that starts an instance of vtsingle and fails the test if the app fails to start.

func (*TestCase) Stop

func (tc *TestCase) Stop()

Stop performs the test case clean up, such as closing all client connections and removing the -storageDataDir directory.

Note that the -storageDataDir is not removed in case of test case failure to allow for further manual debugging.

func (*TestCase) StopApp

func (tc *TestCase) StopApp(instance string)

StopApp stops the app identified by the `instance` name and removes it from the collection of started apps.

func (*TestCase) T

func (tc *TestCase) T() *testing.T

T returns the test state.

type TracesResponseData

type TracesResponseData struct {
	Processes map[string]Process `json:"processes"`
	Spans     []Span             `json:"spans"`
	TraceID   string             `json:"traceID"`
	Warnings  interface{}        `json:"warnings"`
}

TracesResponseData is the structure of `data` field of the /select/jaeger/traces and /select/jaeger/traces/<trace_id> response.

type VictoriaTracesWriteQuerier

type VictoriaTracesWriteQuerier interface {
	OTLPTracesWriter
	JaegerQuerier
	LogsQLQuerier

	StorageFlusher
	StorageMerger
}

VictoriaTracesWriteQuerier encompasses the methods for writing, flushing and querying the trace data.

type Vtsingle

type Vtsingle struct {
	*ServesMetrics
	// contains filtered or unexported fields
}

Vtsingle holds the state of a Vtsingle app and provides Vtsingle-specific functions.

func StartVtsingle

func StartVtsingle(instance string, flags []string, cli *Client) (*Vtsingle, error)

StartVtsingle starts an instance of Vtsingle with the given flags. It also sets the default flags and populates the app instance state with runtime values extracted from the application log (such as httpListenAddr).

func (*Vtsingle) ForceFlush

func (app *Vtsingle) ForceFlush(t *testing.T)

ForceFlush is a test helper function that forces the flushing of inserted data, so it becomes available for searching immediately.

func (*Vtsingle) ForceMerge

func (app *Vtsingle) ForceMerge(t *testing.T)

ForceMerge is a test helper function that forces the merging of parts.

func (*Vtsingle) HTTPAddr

func (app *Vtsingle) HTTPAddr() string

HTTPAddr returns the address at which the vtstorage process is listening for http connections.

func (*Vtsingle) JaegerAPIDependencies

func (app *Vtsingle) JaegerAPIDependencies(t *testing.T, param JaegerDependenciesParam, opts QueryOpts) *JaegerAPIDependenciesResponse

JaegerAPIDependencies is a test helper function that queries for the dependencies. This method is not implemented in Vtsingle and this test is no-op for now.

func (*Vtsingle) JaegerAPIOperations

func (app *Vtsingle) JaegerAPIOperations(t *testing.T, serviceName string, opts QueryOpts) *JaegerAPIOperationsResponse

JaegerAPIOperations is a test helper function that queries for operation list of a service by sending an HTTP GET request to /select/jaeger/api/services/<service_name>/operations Vtsingle endpoint.

func (*Vtsingle) JaegerAPIServices

func (app *Vtsingle) JaegerAPIServices(t *testing.T, opts QueryOpts) *JaegerAPIServicesResponse

JaegerAPIServices is a test helper function that queries for service list by sending an HTTP GET request to /select/jaeger/api/services Vtsingle endpoint.

func (*Vtsingle) JaegerAPITrace

func (app *Vtsingle) JaegerAPITrace(t *testing.T, traceID string, opts QueryOpts) *JaegerAPITraceResponse

JaegerAPITrace is a test helper function that queries for a single trace with trace_id by sending an HTTP GET request to /select/jaeger/api/traces/<trace_id> Vtsingle endpoint.

func (*Vtsingle) JaegerAPITraces

func (app *Vtsingle) JaegerAPITraces(t *testing.T, param JaegerQueryParam, opts QueryOpts) *JaegerAPITracesResponse

JaegerAPITraces is a test helper function that queries for traces with filter conditions by sending an HTTP GET request to /select/jaeger/api/traces Vtsingle endpoint.

func (*Vtsingle) LogsQLQuery added in v0.6.0

func (app *Vtsingle) LogsQLQuery(t *testing.T, LogsQL string, opts QueryOpts) *LogsQLQueryResponse

func (Vtsingle) Name

func (app Vtsingle) Name() string

Name returns the application instance name.

func (*Vtsingle) OTLPHTTPExportRawTraces added in v0.6.0

func (app *Vtsingle) OTLPHTTPExportRawTraces(t *testing.T, data []byte, opts QueryOpts)

OTLPHTTPExportRawTraces is a test helper function that exports raw OTLP trace data in []byte by sending an HTTP POST request to /insert/opentelemetry/v1/traces Vtsingle endpoint.

func (*Vtsingle) OTLPHTTPExportTraces added in v0.5.0

func (app *Vtsingle) OTLPHTTPExportTraces(t *testing.T, request *otelpb.ExportTraceServiceRequest, opts QueryOpts)

OTLPHTTPExportTraces is a test helper function that exports OTLP trace data by sending an HTTP POST request to /insert/opentelemetry/v1/traces Vtsingle endpoint.

func (*Vtsingle) OTLPgRPCExportTraces added in v0.5.0

func (app *Vtsingle) OTLPgRPCExportTraces(t *testing.T, request *otelpb.ExportTraceServiceRequest, _ QueryOpts)

OTLPgRPCExportTraces is a test helper function that exports OTLP trace data by sending an `Export` gRPC call to a TraceService provider (Vtsingle).

func (Vtsingle) Stop

func (app Vtsingle) Stop()

Stop sends the app process a SIGINT signal and waits until it terminates gracefully.

func (*Vtsingle) String

func (app *Vtsingle) String() string

String returns the string representation of the Vtsingle app state.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL