github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/querier/queryrange/split_by_range_test.go (about) 1 package queryrange 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/grafana/loki/pkg/loghttp" 10 11 "github.com/go-kit/log" 12 "github.com/stretchr/testify/require" 13 "github.com/weaveworks/common/user" 14 15 "github.com/grafana/loki/pkg/logproto" 16 "github.com/grafana/loki/pkg/querier/queryrange/queryrangebase" 17 ) 18 19 func Test_RangeVectorSplit(t *testing.T) { 20 srm := NewSplitByRangeMiddleware(log.NewNopLogger(), fakeLimits{ 21 maxSeries: 10000, 22 splits: map[string]time.Duration{ 23 "tenant": time.Minute, 24 }, 25 }, nilShardingMetrics) 26 27 ctx := user.InjectOrgID(context.TODO(), "tenant") 28 29 for _, tc := range []struct { 30 in queryrangebase.Request 31 subQueries []queryrangebase.RequestResponse 32 expected queryrangebase.Response 33 }{ 34 { 35 in: &LokiInstantRequest{ 36 Query: `sum(bytes_over_time({app="foo"}[3m]))`, 37 TimeTs: time.Unix(1, 0), 38 Path: "/loki/api/v1/query", 39 }, 40 subQueries: []queryrangebase.RequestResponse{ 41 subQueryRequestResponse(`sum(bytes_over_time({app="foo"}[1m]))`, 1), 42 subQueryRequestResponse(`sum(bytes_over_time({app="foo"}[1m] offset 1m0s))`, 2), 43 subQueryRequestResponse(`sum(bytes_over_time({app="foo"}[1m] offset 2m0s))`, 3), 44 }, 45 expected: expectedMergedResponse(1 + 2 + 3), 46 }, 47 { 48 in: &LokiInstantRequest{ 49 Query: `sum by (bar) (bytes_over_time({app="foo"}[3m]))`, 50 TimeTs: time.Unix(1, 0), 51 Path: "/loki/api/v1/query", 52 }, 53 subQueries: []queryrangebase.RequestResponse{ 54 subQueryRequestResponse(`sum by(bar)(bytes_over_time({app="foo"}[1m]))`, 10), 55 subQueryRequestResponse(`sum by(bar)(bytes_over_time({app="foo"}[1m] offset 1m0s))`, 20), 56 subQueryRequestResponse(`sum by(bar)(bytes_over_time({app="foo"}[1m] offset 2m0s))`, 30), 57 }, 58 expected: expectedMergedResponse(10 + 20 + 30), 59 }, 60 { 61 in: &LokiInstantRequest{ 62 Query: `sum(count_over_time({app="foo"}[3m]))`, 63 TimeTs: time.Unix(1, 0), 64 Path: "/loki/api/v1/query", 65 }, 66 subQueries: []queryrangebase.RequestResponse{ 67 subQueryRequestResponse(`sum(count_over_time({app="foo"}[1m]))`, 1), 68 subQueryRequestResponse(`sum(count_over_time({app="foo"}[1m] offset 1m0s))`, 1), 69 subQueryRequestResponse(`sum(count_over_time({app="foo"}[1m] offset 2m0s))`, 1), 70 }, 71 expected: expectedMergedResponse(1 + 1 + 1), 72 }, 73 { 74 in: &LokiInstantRequest{ 75 Query: `sum by (bar) (count_over_time({app="foo"}[3m]))`, 76 TimeTs: time.Unix(1, 0), 77 Path: "/loki/api/v1/query", 78 }, 79 subQueries: []queryrangebase.RequestResponse{ 80 subQueryRequestResponse(`sum by(bar)(count_over_time({app="foo"}[1m]))`, 0), 81 subQueryRequestResponse(`sum by(bar)(count_over_time({app="foo"}[1m] offset 1m0s))`, 0), 82 subQueryRequestResponse(`sum by(bar)(count_over_time({app="foo"}[1m] offset 2m0s))`, 0), 83 }, 84 expected: expectedMergedResponse(0 + 0 + 0), 85 }, 86 { 87 in: &LokiInstantRequest{ 88 Query: `sum(sum_over_time({app="foo"} | unwrap bar [3m]))`, 89 TimeTs: time.Unix(1, 0), 90 Path: "/loki/api/v1/query", 91 }, 92 subQueries: []queryrangebase.RequestResponse{ 93 subQueryRequestResponse(`sum(sum_over_time({app="foo"} | unwrap bar[1m]))`, 1), 94 subQueryRequestResponse(`sum(sum_over_time({app="foo"} | unwrap bar[1m] offset 1m0s))`, 2), 95 subQueryRequestResponse(`sum(sum_over_time({app="foo"} | unwrap bar[1m] offset 2m0s))`, 3), 96 }, 97 expected: expectedMergedResponse(1 + 2 + 3), 98 }, 99 { 100 in: &LokiInstantRequest{ 101 Query: `sum by (bar) (sum_over_time({app="foo"} | unwrap bar [3m]))`, 102 TimeTs: time.Unix(1, 0), 103 Path: "/loki/api/v1/query", 104 }, 105 subQueries: []queryrangebase.RequestResponse{ 106 subQueryRequestResponse(`sum by(bar)(sum_over_time({app="foo"} | unwrap bar[1m]))`, 1), 107 subQueryRequestResponse(`sum by(bar)(sum_over_time({app="foo"} | unwrap bar[1m] offset 1m0s))`, 2), 108 subQueryRequestResponse(`sum by(bar)(sum_over_time({app="foo"} | unwrap bar[1m] offset 2m0s))`, 3), 109 }, 110 expected: expectedMergedResponse(1 + 2 + 3), 111 }, 112 } { 113 tc := tc 114 t.Run(tc.in.GetQuery(), func(t *testing.T) { 115 resp, err := srm.Wrap(queryrangebase.HandlerFunc( 116 func(ctx context.Context, req queryrangebase.Request) (queryrangebase.Response, error) { 117 // Assert subquery request 118 for _, reqResp := range tc.subQueries { 119 if req.GetQuery() == reqResp.Request.GetQuery() { 120 require.Equal(t, reqResp.Request, req) 121 // return the test data subquery response 122 return reqResp.Response, nil 123 } 124 } 125 126 return nil, fmt.Errorf("subquery request '" + req.GetQuery() + "' not found") 127 })).Do(ctx, tc.in) 128 require.NoError(t, err) 129 require.Equal(t, tc.expected, resp.(*LokiPromResponse).Response) 130 }) 131 } 132 } 133 134 // subQueryRequestResponse returns a RequestResponse containing the expected subQuery instant request 135 // and a response containing a sample value returned from the following wrapper 136 func subQueryRequestResponse(expectedSubQuery string, sampleValue float64) queryrangebase.RequestResponse { 137 return queryrangebase.RequestResponse{ 138 Request: &LokiInstantRequest{ 139 Query: expectedSubQuery, 140 TimeTs: time.Unix(1, 0), 141 Path: "/loki/api/v1/query", 142 }, 143 Response: &LokiPromResponse{ 144 Response: &queryrangebase.PrometheusResponse{ 145 Status: loghttp.QueryStatusSuccess, 146 Data: queryrangebase.PrometheusData{ 147 ResultType: loghttp.ResultTypeVector, 148 Result: []queryrangebase.SampleStream{ 149 { 150 Labels: []logproto.LabelAdapter{ 151 {Name: "app", Value: "foo"}, 152 }, 153 Samples: []logproto.LegacySample{ 154 {TimestampMs: 1000, Value: sampleValue}, 155 }, 156 }, 157 }, 158 }, 159 }, 160 }, 161 } 162 } 163 164 // expectedMergedResponse returns the expected middleware Prometheus response with the samples 165 // as the expectedSampleValue 166 func expectedMergedResponse(expectedSampleValue float64) *queryrangebase.PrometheusResponse { 167 return &queryrangebase.PrometheusResponse{ 168 Status: loghttp.QueryStatusSuccess, 169 Data: queryrangebase.PrometheusData{ 170 ResultType: loghttp.ResultTypeVector, 171 Result: []queryrangebase.SampleStream{ 172 { 173 Labels: []logproto.LabelAdapter{}, 174 Samples: []logproto.LegacySample{ 175 {TimestampMs: 1000, Value: expectedSampleValue}, 176 }, 177 }, 178 }, 179 }, 180 } 181 }