@@ -234,7 +234,7 @@ func TestLabelsCodec_EncodeRequest(t *testing.T) {
234234 },
235235 {
236236 name : "thanos labels values request" ,
237- req : & ThanosLabelsRequest {Start : 123000 , End : 456000 , Path : "/api/v1/label/__name__/values" },
237+ req : & ThanosLabelsRequest {Start : 123000 , End : 456000 , Path : "/api/v1/label/__name__/values" , Label : "__name__" },
238238 checkFunc : func (r * http.Request ) bool {
239239 return r .URL .Query ().Get (start ) == startTime &&
240240 r .URL .Query ().Get (end ) == endTime &&
@@ -243,7 +243,7 @@ func TestLabelsCodec_EncodeRequest(t *testing.T) {
243243 },
244244 {
245245 name : "thanos labels values request, partial response set to true" ,
246- req : & ThanosLabelsRequest {Start : 123000 , End : 456000 , Path : "/api/v1/label/__name__/values" , PartialResponse : true },
246+ req : & ThanosLabelsRequest {Start : 123000 , End : 456000 , Path : "/api/v1/label/__name__/values" , Label : "__name__" , PartialResponse : true },
247247 checkFunc : func (r * http.Request ) bool {
248248 return r .URL .Query ().Get (start ) == startTime &&
249249 r .URL .Query ().Get (end ) == endTime &&
@@ -313,12 +313,29 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) {
313313 labelsData , err := json .Marshal (labelResponse )
314314 testutil .Ok (t , err )
315315
316+ labelResponseWithHeaders := & ThanosLabelsResponse {
317+ Status : "success" ,
318+ Data : []string {"__name__" },
319+ Headers : []* ResponseHeader {{Name : cacheControlHeader , Values : []string {noStoreValue }}},
320+ }
321+ labelsDataWithHeaders , err := json .Marshal (labelResponseWithHeaders )
322+ testutil .Ok (t , err )
323+
316324 seriesResponse := & ThanosSeriesResponse {
317325 Status : "success" ,
318326 Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}},
319327 }
320328 seriesData , err := json .Marshal (seriesResponse )
321329 testutil .Ok (t , err )
330+
331+ seriesResponseWithHeaders := & ThanosSeriesResponse {
332+ Status : "success" ,
333+ Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}},
334+ Headers : []* ResponseHeader {{Name : cacheControlHeader , Values : []string {noStoreValue }}},
335+ }
336+ seriesDataWithHeaders , err := json .Marshal (seriesResponseWithHeaders )
337+ testutil .Ok (t , err )
338+
322339 for _ , tc := range []struct {
323340 name string
324341 expectedError error
@@ -344,12 +361,34 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) {
344361 res : http.Response {StatusCode : 200 , Body : ioutil .NopCloser (bytes .NewBuffer (labelsData ))},
345362 expectedResponse : labelResponse ,
346363 },
364+ {
365+ name : "thanos labels request with HTTP headers" ,
366+ req : & ThanosLabelsRequest {},
367+ res : http.Response {
368+ StatusCode : 200 , Body : ioutil .NopCloser (bytes .NewBuffer (labelsDataWithHeaders )),
369+ Header : map [string ][]string {
370+ cacheControlHeader : {noStoreValue },
371+ },
372+ },
373+ expectedResponse : labelResponseWithHeaders ,
374+ },
347375 {
348376 name : "thanos series request" ,
349377 req : & ThanosSeriesRequest {},
350378 res : http.Response {StatusCode : 200 , Body : ioutil .NopCloser (bytes .NewBuffer (seriesData ))},
351379 expectedResponse : seriesResponse ,
352380 },
381+ {
382+ name : "thanos series request with HTTP headers" ,
383+ req : & ThanosSeriesRequest {},
384+ res : http.Response {
385+ StatusCode : 200 , Body : ioutil .NopCloser (bytes .NewBuffer (seriesDataWithHeaders )),
386+ Header : map [string ][]string {
387+ cacheControlHeader : {noStoreValue },
388+ },
389+ },
390+ expectedResponse : seriesResponseWithHeaders ,
391+ },
353392 } {
354393 t .Run (tc .name , func (t * testing.T ) {
355394 // Default partial response value doesn't matter when encoding requests.
@@ -364,3 +403,117 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) {
364403 })
365404 }
366405}
406+
407+ func TestLabelsCodec_MergeResponse (t * testing.T ) {
408+ for _ , tc := range []struct {
409+ name string
410+ expectedError error
411+ responses []queryrange.Response
412+ expectedResponse queryrange.Response
413+ }{
414+ {
415+ name : "Prometheus range query response format, not valid" ,
416+ responses : []queryrange.Response {
417+ & queryrange.PrometheusResponse {Status : "success" },
418+ },
419+ expectedError : httpgrpc .Errorf (http .StatusInternalServerError , "invalid response format" ),
420+ },
421+ {
422+ name : "Empty response" ,
423+ responses : nil ,
424+ expectedResponse : & ThanosLabelsResponse {Status : queryrange .StatusSuccess , Data : []string {}},
425+ },
426+ {
427+ name : "One label response" ,
428+ responses : []queryrange.Response {
429+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9090" , "localhost:9091" }},
430+ },
431+ expectedResponse : & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9090" , "localhost:9091" }},
432+ },
433+ {
434+ name : "One label response and two empty responses" ,
435+ responses : []queryrange.Response {
436+ & ThanosLabelsResponse {Status : queryrange .StatusSuccess , Data : []string {}},
437+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9090" , "localhost:9091" }},
438+ & ThanosLabelsResponse {Status : queryrange .StatusSuccess , Data : []string {}},
439+ },
440+ expectedResponse : & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9090" , "localhost:9091" }},
441+ },
442+ {
443+ name : "Multiple duplicate label responses" ,
444+ responses : []queryrange.Response {
445+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9090" , "localhost:9091" }},
446+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9091" , "localhost:9092" }},
447+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9092" , "localhost:9093" }},
448+ },
449+ expectedResponse : & ThanosLabelsResponse {Status : "success" ,
450+ Data : []string {"localhost:9090" , "localhost:9091" , "localhost:9092" , "localhost:9093" }},
451+ },
452+ // This case shouldn't happen because the responses from Querier are sorted.
453+ {
454+ name : "Multiple unordered label responses" ,
455+ responses : []queryrange.Response {
456+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9093" , "localhost:9092" }},
457+ & ThanosLabelsResponse {Status : "success" , Data : []string {"localhost:9091" , "localhost:9090" }},
458+ },
459+ expectedResponse : & ThanosLabelsResponse {Status : "success" ,
460+ Data : []string {"localhost:9090" , "localhost:9091" , "localhost:9092" , "localhost:9093" }},
461+ },
462+ {
463+ name : "One series response" ,
464+ responses : []queryrange.Response {
465+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
466+ },
467+ expectedResponse : & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
468+ },
469+ {
470+ name : "One series response and two empty responses" ,
471+ responses : []queryrange.Response {
472+ & ThanosSeriesResponse {Status : queryrange .StatusSuccess },
473+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
474+ & ThanosSeriesResponse {Status : queryrange .StatusSuccess },
475+ },
476+ expectedResponse : & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
477+ },
478+ {
479+ name : "Multiple duplicate series responses" ,
480+ responses : []queryrange.Response {
481+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
482+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
483+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
484+ },
485+ expectedResponse : & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {{Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}}}},
486+ },
487+ {
488+ name : "Multiple unordered series responses" ,
489+ responses : []queryrange.Response {
490+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {
491+ {Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}},
492+ {Labels : []labelpb.ZLabel {{Name : "test" , Value : "aaa" }, {Name : "instance" , Value : "localhost:9090" }}},
493+ }},
494+ & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {
495+ {Labels : []labelpb.ZLabel {{Name : "foo" , Value : "aaa" }}},
496+ {Labels : []labelpb.ZLabel {{Name : "test" , Value : "bbb" }, {Name : "instance" , Value : "localhost:9091" }}},
497+ }},
498+ },
499+ expectedResponse : & ThanosSeriesResponse {Status : "success" , Data : []labelpb.ZLabelSet {
500+ {Labels : []labelpb.ZLabel {{Name : "foo" , Value : "aaa" }}},
501+ {Labels : []labelpb.ZLabel {{Name : "foo" , Value : "bar" }}},
502+ {Labels : []labelpb.ZLabel {{Name : "test" , Value : "aaa" }, {Name : "instance" , Value : "localhost:9090" }}},
503+ {Labels : []labelpb.ZLabel {{Name : "test" , Value : "bbb" }, {Name : "instance" , Value : "localhost:9091" }}},
504+ }},
505+ },
506+ } {
507+ t .Run (tc .name , func (t * testing.T ) {
508+ // Default partial response value doesn't matter when encoding requests.
509+ codec := NewThanosLabelsCodec (false , time .Hour * 2 )
510+ r , err := codec .MergeResponse (tc .responses ... )
511+ if tc .expectedError != nil {
512+ testutil .Equals (t , err , tc .expectedError )
513+ } else {
514+ testutil .Ok (t , err )
515+ testutil .Equals (t , tc .expectedResponse , r )
516+ }
517+ })
518+ }
519+ }
0 commit comments