Files
21c39b2792 Update prometheus to latest release v2.47.1 (c4d1a8b) (#3001)
* Update prometheus to latest release v2.47.1 (c4d1a8b)

I ran
```
go get github.com/prometheus/prometheus@c4d1a8b
```
And fixed any compilation issues

* Checkin .test files from prometheus

* go mod tidy

* More fixes

* Final set of fixes? 🤞

* Lint

---------

Co-authored-by: Mario <[email protected]>
2023-10-11 13:15:49 +00:00

265 lines
6.5 KiB
Go

package e2e
import (
"context"
"crypto/tls"
"io"
"io/ioutil"
"math"
"math/rand"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/prompb"
)
func RunCommandAndGetOutput(name string, args ...string) ([]byte, error) {
cmd := exec.Command(name, args...)
return cmd.CombinedOutput()
}
func RunCommandWithTimeoutAndGetOutput(timeout time.Duration, name string, args ...string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, name, args...)
return cmd.CombinedOutput()
}
func EmptyFlags() map[string]string {
return map[string]string{}
}
func MergeFlags(inputs ...map[string]string) map[string]string {
output := MergeFlagsWithoutRemovingEmpty(inputs...)
for k, v := range output {
if v == "" {
delete(output, k)
}
}
return output
}
func MergeFlagsWithoutRemovingEmpty(inputs ...map[string]string) map[string]string {
output := map[string]string{}
for _, input := range inputs {
for name, value := range input {
output[name] = value
}
}
return output
}
func BuildArgs(flags map[string]string) []string {
args := make([]string, 0, len(flags))
for name, value := range flags {
if value != "" {
args = append(args, name+"="+value)
} else {
args = append(args, name)
}
}
return args
}
// DoGet performs an HTTP GET request towards the supplied URL and using a
// timeout of 1 second.
func DoGet(url string) (*http.Response, error) {
return doRequestWithTimeout("GET", url, nil, nil, time.Second)
}
// DoGetWithTimeout performs an HTTP GET request towards the supplied URL and using a
// specified timeout.
func DoGetWithTimeout(url string, timeout time.Duration) (*http.Response, error) {
return doRequestWithTimeout("GET", url, nil, nil, timeout)
}
// DoGetTLS is like DoGet but allows to configure a TLS config.
func DoGetTLS(url string, tlsConfig *tls.Config) (*http.Response, error) {
return doRequestWithTimeout("GET", url, nil, tlsConfig, time.Second)
}
// DoPost performs a HTTP POST request towards the supplied URL with an empty
// body and using a timeout of 1 second.
func DoPost(url string) (*http.Response, error) {
return doRequestWithTimeout("POST", url, strings.NewReader(""), nil, time.Second)
}
func doRequestWithTimeout(method, url string, body io.Reader, tlsConfig *tls.Config, timeout time.Duration) (*http.Response, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
client := &http.Client{
Timeout: timeout,
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
return client.Do(req)
}
// TimeToMilliseconds returns the input time as milliseconds, using the same
// formula used by Prometheus in order to get the same timestamp when asserting
// on query results. The formula we're mimicking here is Prometheus parseTime().
// See: https://github.com/prometheus/prometheus/blob/df80dc4d3970121f2f76cba79050983ffb3cdbb0/web/api/v1/api.go#L1690-L1694
func TimeToMilliseconds(t time.Time) int64 {
// Convert to seconds.
sec := float64(t.Unix()) + float64(t.Nanosecond())/1e9
// Parse seconds.
s, ns := math.Modf(sec)
// Round nanoseconds part.
ns = math.Round(ns*1000) / 1000
// Convert to millis.
return (int64(s) * 1e3) + (int64(ns * 1e3))
}
func GenerateSeries(name string, ts time.Time, additionalLabels ...prompb.Label) (series []prompb.TimeSeries, vector model.Vector, matrix model.Matrix) {
tsMillis := TimeToMilliseconds(ts)
value := rand.Float64()
lbls := append(
[]prompb.Label{
{Name: labels.MetricName, Value: name},
},
additionalLabels...,
)
// Generate the series
series = append(series, prompb.TimeSeries{
Labels: lbls,
Exemplars: []prompb.Exemplar{
{Value: value, Timestamp: tsMillis, Labels: []prompb.Label{
{Name: "trace_id", Value: "1234"},
}},
},
Samples: []prompb.Sample{
{Value: value, Timestamp: tsMillis},
},
})
// Generate the expected vector and matrix when querying it
metric := model.Metric{}
metric[labels.MetricName] = model.LabelValue(name)
for _, lbl := range additionalLabels {
metric[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
}
vector = append(vector, &model.Sample{
Metric: metric,
Value: model.SampleValue(value),
Timestamp: model.Time(tsMillis),
})
matrix = append(matrix, &model.SampleStream{
Metric: metric,
Values: []model.SamplePair{
{
Timestamp: model.Time(tsMillis),
Value: model.SampleValue(value),
},
},
})
return
}
func GenerateNSeries(nSeries, nExemplars int, name func() string, ts time.Time, additionalLabels func() []prompb.Label) (series []prompb.TimeSeries, vector model.Vector) {
tsMillis := TimeToMilliseconds(ts)
// Generate the series
for i := 0; i < nSeries; i++ {
lbls := []prompb.Label{
{Name: labels.MetricName, Value: name()},
}
if additionalLabels != nil {
lbls = append(lbls, additionalLabels()...)
}
value := rand.Float64()
exemplars := []prompb.Exemplar{}
if i < nExemplars {
exemplars = []prompb.Exemplar{
{Value: value, Timestamp: tsMillis, Labels: []prompb.Label{{Name: "trace_id", Value: "1234"}}},
}
}
series = append(series, prompb.TimeSeries{
Labels: lbls,
Samples: []prompb.Sample{
{Value: value, Timestamp: tsMillis},
},
Exemplars: exemplars,
})
}
// Generate the expected vector when querying it
for i := 0; i < nSeries; i++ {
metric := model.Metric{}
for _, lbl := range series[i].Labels {
metric[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
}
vector = append(vector, &model.Sample{
Metric: metric,
Value: model.SampleValue(series[i].Samples[0].Value),
Timestamp: model.Time(tsMillis),
})
}
return
}
// GetTempDirectory creates a temporary directory for shared integration
// test files, either in the working directory or a directory referenced by
// the E2E_TEMP_DIR environment variable
func GetTempDirectory() (string, error) {
var (
dir string
err error
)
// If a temp dir is referenced, return that
if os.Getenv("E2E_TEMP_DIR") != "" {
dir = os.Getenv("E2E_TEMP_DIR")
} else {
dir, err = os.Getwd()
if err != nil {
return "", err
}
}
tmpDir, err := ioutil.TempDir(dir, "e2e_integration_test")
if err != nil {
return "", err
}
// Allow use of the temporary directory for testing with non-root
// users.
if err := os.Chmod(tmpDir, 0777); err != nil {
return "", err
}
absDir, err := filepath.Abs(tmpDir)
if err != nil {
_ = os.RemoveAll(tmpDir)
return "", err
}
return absDir, nil
}