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 }