github.com/m3db/m3@v1.5.0/scripts/comparator/utils/compare_utilities.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package utils 22 23 import ( 24 "encoding/json" 25 "io/ioutil" 26 "net/url" 27 "os" 28 "strconv" 29 30 "go.uber.org/zap" 31 ) 32 33 // InputQueries is a slice of InputQuery. 34 type InputQueries []InputQuery 35 36 // InputQuery is the JSON representation of a query to be compared. 37 type InputQuery struct { 38 // QueryGroup is the general category for these queries. 39 QueryGroup string `json:"queryGroup"` 40 // Queries is the list of raw queries. 41 Queries []string `json:"queries"` 42 // Steps is the list of step sizes for these queries. 43 Steps []string `json:"steps"` 44 // Reruns is the number of times to rerun this query group. 45 Reruns int `json:"reruns"` 46 } 47 48 // PromQLQueryGroup is a list of constructed PromQL query groups. 49 type PromQLQueryGroup struct { 50 // QueryGroup is the general category for these queries. 51 QueryGroup string 52 // Queries is a list of PromQL compatible queries. 53 Queries []string 54 // Reruns is the number of times to rerun this query group. 55 Reruns int 56 } 57 58 func (q InputQueries) constructPromQL( 59 start int64, 60 end int64, 61 ) []PromQLQueryGroup { 62 queries := make([]PromQLQueryGroup, 0, len(q)) 63 for _, inQuery := range q { 64 queries = append(queries, inQuery.constructPromQL(start, end)) 65 } 66 67 return queries 68 } 69 70 func (q InputQuery) constructPromQL(start int64, end int64) PromQLQueryGroup { 71 queries := make([]string, 0, len(q.Queries)*len(q.Steps)) 72 for _, inQuery := range q.Queries { 73 for _, inStep := range q.Steps { 74 queryRangeValues := make(url.Values) 75 queryRangeValues.Add("query", inQuery) 76 queryRangeValues.Add("step", inStep) 77 queryRangeValues.Add("start", strconv.Itoa(int(start))) 78 queryRangeValues.Add("end", strconv.Itoa(int(end))) 79 queryRangePath := "/api/v1/query_range?" + queryRangeValues.Encode() 80 81 queryValues := make(url.Values) 82 queryValues.Add("query", inQuery) 83 queryValues.Add("time", strconv.Itoa(int(start))) 84 queryPath := "/api/v1/query?" + queryValues.Encode() 85 86 queries = append(queries, queryRangePath, queryPath) 87 } 88 } 89 90 runs := 1 91 if q.Reruns > 1 { 92 runs = q.Reruns 93 } 94 95 return PromQLQueryGroup{ 96 QueryGroup: q.QueryGroup, 97 Queries: queries, 98 Reruns: runs, 99 } 100 } 101 102 func parseFileToQueries( 103 fileName string, 104 log *zap.Logger, 105 ) (InputQueries, error) { 106 file, err := os.Open(fileName) 107 if err != nil { 108 log.Error("could not open file", zap.Error(err)) 109 return nil, err 110 } 111 112 defer file.Close() 113 buf, err := ioutil.ReadAll(file) 114 if err != nil { 115 log.Error("could not read file", zap.Error(err)) 116 return nil, err 117 } 118 119 queries := make(InputQueries, 0, 10) 120 if err := json.Unmarshal(buf, &queries); err != nil { 121 log.Error("could not unmarshal queries", zap.Error(err)) 122 return nil, err 123 } 124 125 return queries, err 126 } 127 128 // ParseFileToPromQLQueryGroup parses a JSON queries file 129 // into PromQL query groups. 130 func ParseFileToPromQLQueryGroup( 131 fileName string, 132 start int64, 133 end int64, 134 log *zap.Logger, 135 ) ([]PromQLQueryGroup, error) { 136 queries, err := parseFileToQueries(fileName, log) 137 if err != nil { 138 return nil, err 139 } 140 141 return queries.constructPromQL(start, end), nil 142 }