github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/integration/e2e/util.go (about)

     1  package e2e
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"math"
     7  	"math/rand"
     8  	"net/http"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"strings"
    13  	"time"
    14  
    15  	"github.com/prometheus/common/model"
    16  	"github.com/prometheus/prometheus/pkg/labels"
    17  	"github.com/prometheus/prometheus/prompb"
    18  )
    19  
    20  func RunCommandAndGetOutput(name string, args ...string) ([]byte, error) {
    21  	cmd := exec.Command(name, args...)
    22  	return cmd.CombinedOutput()
    23  }
    24  
    25  func RunCommandWithTimeoutAndGetOutput(timeout time.Duration, name string, args ...string) ([]byte, error) {
    26  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
    27  	defer cancel()
    28  
    29  	cmd := exec.CommandContext(ctx, name, args...)
    30  	return cmd.CombinedOutput()
    31  }
    32  
    33  func EmptyFlags() map[string]string {
    34  	return map[string]string{}
    35  }
    36  
    37  func MergeFlags(inputs ...map[string]string) map[string]string {
    38  	output := MergeFlagsWithoutRemovingEmpty(inputs...)
    39  
    40  	for k, v := range output {
    41  		if v == "" {
    42  			delete(output, k)
    43  		}
    44  	}
    45  
    46  	return output
    47  }
    48  
    49  func MergeFlagsWithoutRemovingEmpty(inputs ...map[string]string) map[string]string {
    50  	output := map[string]string{}
    51  
    52  	for _, input := range inputs {
    53  		for name, value := range input {
    54  			output[name] = value
    55  		}
    56  	}
    57  
    58  	return output
    59  }
    60  
    61  func BuildArgs(flags map[string]string) []string {
    62  	args := make([]string, 0, len(flags))
    63  
    64  	for name, value := range flags {
    65  		if value != "" {
    66  			args = append(args, name+"="+value)
    67  		} else {
    68  			args = append(args, name)
    69  		}
    70  	}
    71  
    72  	return args
    73  }
    74  
    75  func GetRequest(url string) (*http.Response, error) {
    76  	const timeout = 1 * time.Second
    77  
    78  	client := &http.Client{Timeout: timeout}
    79  	return client.Get(url)
    80  }
    81  
    82  func PostRequest(url string) (*http.Response, error) {
    83  	const timeout = 1 * time.Second
    84  
    85  	client := &http.Client{Timeout: timeout}
    86  	return client.Post(url, "", strings.NewReader(""))
    87  }
    88  
    89  // TimeToMilliseconds returns the input time as milliseconds, using the same
    90  // formula used by Prometheus in order to get the same timestamp when asserting
    91  // on query results. The formula we're mimicking here is Prometheus parseTime().
    92  // See: https://github.com/prometheus/prometheus/blob/df80dc4d3970121f2f76cba79050983ffb3cdbb0/web/api/v1/api.go#L1690-L1694
    93  func TimeToMilliseconds(t time.Time) int64 {
    94  	// Convert to seconds.
    95  	sec := float64(t.Unix()) + float64(t.Nanosecond())/1e9
    96  
    97  	// Parse seconds.
    98  	s, ns := math.Modf(sec)
    99  
   100  	// Round nanoseconds part.
   101  	ns = math.Round(ns*1000) / 1000
   102  
   103  	// Convert to millis.
   104  	return (int64(s) * 1e3) + (int64(ns * 1e3))
   105  }
   106  
   107  func GenerateSeries(name string, ts time.Time, additionalLabels ...prompb.Label) (series []prompb.TimeSeries, vector model.Vector) {
   108  	tsMillis := TimeToMilliseconds(ts)
   109  	value := rand.Float64()
   110  
   111  	lbls := append(
   112  		[]prompb.Label{
   113  			{Name: labels.MetricName, Value: name},
   114  		},
   115  		additionalLabels...,
   116  	)
   117  
   118  	// Generate the series
   119  	series = append(series, prompb.TimeSeries{
   120  		Labels: lbls,
   121  		Samples: []prompb.Sample{
   122  			{Value: value, Timestamp: tsMillis},
   123  		},
   124  	})
   125  
   126  	// Generate the expected vector when querying it
   127  	metric := model.Metric{}
   128  	metric[labels.MetricName] = model.LabelValue(name)
   129  	for _, lbl := range additionalLabels {
   130  		metric[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
   131  	}
   132  
   133  	vector = append(vector, &model.Sample{
   134  		Metric:    metric,
   135  		Value:     model.SampleValue(value),
   136  		Timestamp: model.Time(tsMillis),
   137  	})
   138  
   139  	return
   140  }
   141  
   142  // GetTempDirectory creates a temporary directory for shared integration
   143  // test files, either in the working directory or a directory referenced by
   144  // the E2E_TEMP_DIR environment variable
   145  func GetTempDirectory() (string, error) {
   146  	var (
   147  		dir string
   148  		err error
   149  	)
   150  	// If a temp dir is referenced, return that
   151  	if os.Getenv("E2E_TEMP_DIR") != "" {
   152  		dir = os.Getenv("E2E_TEMP_DIR")
   153  	} else {
   154  		dir, err = os.Getwd()
   155  		if err != nil {
   156  			return "", err
   157  		}
   158  	}
   159  
   160  	tmpDir, err := ioutil.TempDir(dir, "e2e_integration_test")
   161  	if err != nil {
   162  		return "", err
   163  	}
   164  	absDir, err := filepath.Abs(tmpDir)
   165  	if err != nil {
   166  		_ = os.RemoveAll(tmpDir)
   167  		return "", err
   168  	}
   169  
   170  	return absDir, nil
   171  }