2025-04-08 17:12:06 +03:00
|
|
|
package apptest
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2025-08-01 16:21:14 +04:00
|
|
|
"io"
|
2025-04-08 17:12:06 +03:00
|
|
|
"net/http"
|
2025-04-17 19:23:42 +03:00
|
|
|
"os"
|
2025-04-08 17:12:06 +03:00
|
|
|
"regexp"
|
|
|
|
|
"strings"
|
2025-06-13 15:35:50 +03:00
|
|
|
"syscall"
|
2025-04-08 17:12:06 +03:00
|
|
|
"testing"
|
|
|
|
|
"time"
|
2026-04-24 13:36:35 +02:00
|
|
|
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prommetadata"
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompb"
|
|
|
|
|
"github.com/golang/snappy"
|
2025-04-08 17:12:06 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Vmagent holds the state of a vmagent app and provides vmagent-specific functions
|
|
|
|
|
type Vmagent struct {
|
|
|
|
|
*app
|
2026-05-12 16:24:01 +02:00
|
|
|
*metricsClient
|
2025-04-08 17:12:06 +03:00
|
|
|
|
2026-05-06 17:49:54 +02:00
|
|
|
httpListenAddr string
|
2026-05-12 16:24:01 +02:00
|
|
|
|
|
|
|
|
cli *Client
|
2025-04-08 17:12:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StartVmagent starts an instance of vmagent 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)
|
2025-08-01 16:21:14 +04:00
|
|
|
func StartVmagent(instance string, flags []string, cli *Client, promScrapeConfigFilePath string, output io.Writer) (*Vmagent, error) {
|
2025-04-08 17:12:06 +03:00
|
|
|
extractREs := []*regexp.Regexp{
|
|
|
|
|
httpListenAddrRE,
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 21:37:47 +02:00
|
|
|
app, stderrExtracts, err := startApp(instance, "../../bin/vmagent-race", flags, &appOptions{
|
2025-04-08 17:12:06 +03:00
|
|
|
defaultFlags: map[string]string{
|
2025-04-17 19:23:42 +03:00
|
|
|
"-httpListenAddr": "127.0.0.1:0",
|
|
|
|
|
"-promscrape.config": promScrapeConfigFilePath,
|
|
|
|
|
"-remoteWrite.tmpDataPath": fmt.Sprintf("%s/%s-%d", os.TempDir(), instance, time.Now().UnixNano()),
|
2025-04-08 17:12:06 +03:00
|
|
|
},
|
|
|
|
|
extractREs: extractREs,
|
2025-08-01 16:21:14 +04:00
|
|
|
output: output,
|
2025-04-08 17:12:06 +03:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &Vmagent{
|
2026-05-12 16:24:01 +02:00
|
|
|
app: app,
|
|
|
|
|
metricsClient: newMetricsClient(cli, stderrExtracts[0]),
|
2026-05-06 17:49:54 +02:00
|
|
|
httpListenAddr: stderrExtracts[0],
|
2026-05-12 16:24:01 +02:00
|
|
|
cli: cli,
|
2025-04-08 17:12:06 +03:00
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// APIV1ImportPrometheus is a test helper function that inserts a
|
|
|
|
|
// collection of records in Prometheus text exposition format for the given
|
|
|
|
|
// tenant by sending a HTTP POST request to /api/v1/import/prometheus vmagent endpoint.
|
|
|
|
|
//
|
|
|
|
|
// The call is blocked until the data is flushed to vmstorage or the timeout is reached.
|
|
|
|
|
//
|
2025-04-30 22:51:51 +02:00
|
|
|
// See https://docs.victoriametrics.com/victoriametrics/url-examples/#apiv1importprometheus
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
func (app *Vmagent) APIV1ImportPrometheus(t *testing.T, records []string, opts QueryOpts) {
|
2025-04-08 17:12:06 +03:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
|
|
app.sendBlocking(t, len(records), func() {
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
app.APIV1ImportPrometheusNoWaitFlush(t, records, opts)
|
2025-04-08 17:12:06 +03:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
// APIV1ImportPrometheusNoWaitFlush is a test helper function that inserts a
|
|
|
|
|
// collection of records in Prometheus text exposition format for the given
|
|
|
|
|
// tenant by sending a HTTP POST request to /api/v1/import/prometheus vmagent endpoint.
|
|
|
|
|
//
|
|
|
|
|
// The call accepts the records but does not guarantee successful flush to vmstorage.
|
|
|
|
|
// Flushing may still be in progress on the function return.
|
|
|
|
|
//
|
2025-04-30 22:51:51 +02:00
|
|
|
// See https://docs.victoriametrics.com/victoriametrics/url-examples/#apiv1importprometheus
|
2026-04-16 15:03:19 +02:00
|
|
|
func (app *Vmagent) APIV1ImportPrometheusNoWaitFlush(t *testing.T, records []string, opts QueryOpts) {
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
|
|
data := []byte(strings.Join(records, "\n"))
|
2026-04-16 15:03:19 +02:00
|
|
|
headers := opts.getHeaders()
|
|
|
|
|
headers.Set("Content-Type", "text/plain")
|
2026-05-06 17:49:54 +02:00
|
|
|
url := getVMAgentInsertPath(app.httpListenAddr, "prometheus/api/v1/import/prometheus", opts)
|
|
|
|
|
_, statusCode := app.cli.Post(t, url, data, headers)
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
if statusCode != http.StatusNoContent {
|
|
|
|
|
t.Fatalf("unexpected status code: got %d, want %d", statusCode, http.StatusNoContent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 17:49:54 +02:00
|
|
|
// getVMAgentInsertPath returns URL path for writes.
|
|
|
|
|
// If tenant is set in QueryOpts, it will return cluster-like path for ingestion.
|
|
|
|
|
// If tenant is empty, it will return single-node (no tenants) path.
|
|
|
|
|
func getVMAgentInsertPath(addr, suffix string, o QueryOpts) string {
|
|
|
|
|
if o.Tenant != "" {
|
|
|
|
|
// QueryOpts.Tenant has priority over headers
|
|
|
|
|
return fmt.Sprintf("http://%s/insert/%s/%s", addr, o.Tenant, suffix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h := o.getHeaders()
|
|
|
|
|
if h.Get("AccountID") != "" || h.Get("ProjectID") != "" {
|
|
|
|
|
// vmagent supports tenantID in HTTP headers only if -enableMultitenantHandlers and -enableMultitenancyViaHeaders are set
|
|
|
|
|
// see https://docs.victoriametrics.com/victoriametrics/vmagent/#multitenancy
|
|
|
|
|
return fmt.Sprintf("http://%s/insert/%s", addr, suffix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// tenant is missing in QueryOpts and in HTTP headers. Use single-node (no tenants) path
|
|
|
|
|
return fmt.Sprintf("http://%s/%s", addr, suffix)
|
|
|
|
|
}
|
|
|
|
|
|
vmagent/client: Use VictoriaMetrics remote write protocol by default, downgrade to Prometheus if needed (#8462)
### Describe Your Changes
This commit improves how vmagent selects the remote write protocol.
Previously, vmagent [performed a handshake
probe](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/lib/protoparser/protoparserutil/vmproto_handshake.go#L11)
at
[startup](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/0ff1a3b1540d88b89412712fb0e79283111ad4fa/app/vmagent/remotewrite/client.go#L173):
- If the probe succeeded, it used the VictoriaMetrics (VM) protocol.
- If the probe failed, it downgraded to the Prometheus protocol.
- No protocol changes occurred after the initial probe at runtime.
However, this approach had limitations:
- If vmstorage was unavailable during vmagent startup, vmagent would
immediately downgrade to the Prometheus protocol, leading to higher
network usage unitl vmagent restarted. This case has been reported in
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615.
- If the remote write server was updated or downgraded (e.g., during a
fallback or migration), vmagent would not detect the protocol change. It
would continue retrying failed requests and eventually drop them.
Require a restart of vmagent to pick up the new protocol.
This commit introduces a more adaptive mechanism.
vmagent always starts with the VM protocol and downgrades to the
Prometheus protocol only if an unsupported media type or bad request
response is received.
When this happens, the protocol is downgraded for all future requests.
In-flight requests are re-packed from Zstd to Snappy and retried
immediately.
Snappy-encoded requests are dropped if an unsupported media type or bad
request is received (no retrying).
Additionally, the in-memory and persisted queues could mix snappy and
zstd encoded blocks. The proper encoding is decided before sending by
encoding.IsZstd function.
TODO:
* [x] Add tests
* [x] Update documentation
* [x] Changelog
* [x] Research on
[content-type](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786918054),
[accept-encoding](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8462#issuecomment-2786923382)
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7615#top
issue.
### Checklist
The following checks are **mandatory**:
- [x] My change adheres [VictoriaMetrics contributing
guidelines](https://docs.victoriametrics.com/contributing/).
2025-04-12 10:39:47 +03:00
|
|
|
// RemoteWriteRequestsRetriesCountTotal sums up the total retries for remote write requests.
|
|
|
|
|
func (app *Vmagent) RemoteWriteRequestsRetriesCountTotal(t *testing.T) int {
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByPrefix(t, "vmagent_remotewrite_retries_count_total") {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoteWritePacketsDroppedTotal sums up the total number of dropped remote write packets.
|
|
|
|
|
func (app *Vmagent) RemoteWritePacketsDroppedTotal(t *testing.T) int {
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByPrefix(t, "vmagent_remotewrite_packets_dropped_total") {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 16:11:08 +02:00
|
|
|
// RemoteWriteSamplesDropped sums up the total number of dropped remote write samples for given remote write URL.
|
|
|
|
|
func (app *Vmagent) RemoteWriteSamplesDropped(t *testing.T, url string) int {
|
|
|
|
|
re := regexp.MustCompile(fmt.Sprintf("vmagent_remotewrite_samples_dropped_total{.*url=%q.*}", url))
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByRegexp(t, re) {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoteWritePendingInmemoryBlocks sums up the total number of pending in-memory blocks for given remote write URL.
|
|
|
|
|
func (app *Vmagent) RemoteWritePendingInmemoryBlocks(t *testing.T, url string) int {
|
|
|
|
|
re := regexp.MustCompile(fmt.Sprintf("vmagent_remotewrite_pending_inmemory_blocks{.*url=%q.*}", url))
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByRegexp(t, re) {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoteWriteRequests sums up the total number of sending requests for given remote write URL.
|
|
|
|
|
func (app *Vmagent) RemoteWriteRequests(t *testing.T, url string) int {
|
|
|
|
|
re := regexp.MustCompile(fmt.Sprintf("vmagent_remotewrite_requests_total{.*url=%q.*}", url))
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByRegexp(t, re) {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 15:35:50 +03:00
|
|
|
// ReloadRelabelConfigs sends SIGHUP to trigger relabel config reload
|
|
|
|
|
// and waits until vmagent_relabel_config_reloads_total increases.
|
|
|
|
|
// Fails the test if no reload is detected within 3 seconds.
|
|
|
|
|
func (app *Vmagent) ReloadRelabelConfigs(t *testing.T) {
|
|
|
|
|
prevTotal := app.GetMetric(t, "vmagent_relabel_config_reloads_total")
|
|
|
|
|
|
|
|
|
|
if err := app.process.Signal(syscall.SIGHUP); err != nil {
|
|
|
|
|
t.Fatalf("could not send SIGHUP signal to %s process: %v", app.instance, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var currTotal float64
|
2026-02-18 12:21:07 +01:00
|
|
|
for range 30 {
|
2025-06-13 15:35:50 +03:00
|
|
|
currTotal = app.GetMetric(t, "vmagent_relabel_config_reloads_total")
|
|
|
|
|
if currTotal > prevTotal {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-13 14:05:15 +03:00
|
|
|
t.Fatalf("relabel configs were not reloaded after SIGHUP signal; previous total: %f, current total: %f", prevTotal, currTotal)
|
2025-06-13 15:35:50 +03:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 13:36:35 +02:00
|
|
|
// PrometheusAPIV1Write is a test helper function that inserts a
|
|
|
|
|
// collection of records in Prometheus remote-write format by sending a HTTP
|
|
|
|
|
// POST request to /prometheus/api/v1/write vmagent endpoint.
|
|
|
|
|
func (app *Vmagent) PrometheusAPIV1Write(t *testing.T, wr prompb.WriteRequest, opts QueryOpts) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
|
2026-05-06 17:49:54 +02:00
|
|
|
url := getVMAgentInsertPath(app.httpListenAddr, "prometheus/api/v1/write", opts)
|
2026-04-24 13:36:35 +02:00
|
|
|
data := snappy.Encode(nil, wr.MarshalProtobuf(nil))
|
|
|
|
|
recordsCount := len(wr.Timeseries)
|
|
|
|
|
if prommetadata.IsEnabled() {
|
|
|
|
|
recordsCount += len(wr.Metadata)
|
|
|
|
|
}
|
|
|
|
|
headers := opts.getHeaders()
|
|
|
|
|
headers.Set("Content-Type", "application/x-protobuf")
|
|
|
|
|
app.sendBlocking(t, recordsCount, func() {
|
|
|
|
|
_, statusCode := app.cli.Post(t, url, data, headers)
|
|
|
|
|
if statusCode != http.StatusNoContent {
|
|
|
|
|
t.Fatalf("unexpected status code: got %d, want %d", statusCode, http.StatusNoContent)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-27 20:52:46 +08:00
|
|
|
// HTTPAddr returns the address at which the vmagent process is listening
|
|
|
|
|
// for http connections.
|
|
|
|
|
func (app *Vmagent) HTTPAddr() string {
|
|
|
|
|
return app.httpListenAddr
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-08 17:12:06 +03:00
|
|
|
// sendBlocking sends the data to vmstorage by executing `send` function and
|
|
|
|
|
// waits until the data is actually sent.
|
|
|
|
|
//
|
|
|
|
|
// vmagent does not send the data immediately. It first puts the data into a
|
|
|
|
|
// buffer. Then a background goroutine takes the data from the buffer sends it
|
|
|
|
|
// to the vmstorage. This happens every 1s by default.
|
|
|
|
|
//
|
|
|
|
|
// Waiting is implemented a retrieving the value of `vmagent_remotewrite_requests_total`
|
|
|
|
|
// metric and checking whether it is equal or greater than the wanted value.
|
|
|
|
|
// If it is, then the data has been sent to vmstorage.
|
|
|
|
|
//
|
|
|
|
|
// Unreliable if the records are inserted concurrently.
|
2026-04-24 13:36:35 +02:00
|
|
|
func (app *Vmagent) sendBlocking(t *testing.T, _ int, send func()) {
|
2025-04-08 17:12:06 +03:00
|
|
|
t.Helper()
|
|
|
|
|
|
2026-04-24 13:36:35 +02:00
|
|
|
currRowsSentCount := app.remoteWriteRequestsTotal(t)
|
|
|
|
|
|
2025-04-08 17:12:06 +03:00
|
|
|
send()
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
retries = 20
|
|
|
|
|
period = 100 * time.Millisecond
|
|
|
|
|
)
|
2026-04-24 13:36:35 +02:00
|
|
|
// TODO: properly account wantRowsSentCount
|
|
|
|
|
// currently vmagent doesn't expose per time-series write information
|
|
|
|
|
// so we can only account number of blocks sent via remote write protocol
|
|
|
|
|
// it should be suitable for tests purpose
|
|
|
|
|
wantRowsSentCount := currRowsSentCount + 1
|
2025-04-08 17:12:06 +03:00
|
|
|
for range retries {
|
|
|
|
|
if app.remoteWriteRequestsTotal(t) >= wantRowsSentCount {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(period)
|
|
|
|
|
}
|
|
|
|
|
t.Fatalf("timed out while waiting for inserted rows to be sent to vmstorage")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (app *Vmagent) remoteWriteRequestsTotal(t *testing.T) int {
|
|
|
|
|
total := 0.0
|
|
|
|
|
for _, v := range app.GetMetricsByPrefix(t, "vmagent_remotewrite_requests_total") {
|
|
|
|
|
total += v
|
|
|
|
|
}
|
|
|
|
|
return int(total)
|
|
|
|
|
}
|