@@ -1897,3 +1897,190 @@ func createBlockWithOneSeriesWithStep(t testutil.TB, dir string, lbls labels.Lab
1897
1897
1898
1898
return createBlockFromHead (t , dir , h )
1899
1899
}
1900
+
1901
+ func TestLabelNamesAndValuesHints (t * testing.T ) {
1902
+ tb := testutil .NewTB (t )
1903
+
1904
+ tmpDir , err := ioutil .TempDir ("" , "test-labels-hints" )
1905
+ testutil .Ok (t , err )
1906
+ defer func () { testutil .Ok (t , os .RemoveAll (tmpDir )) }()
1907
+
1908
+ bktDir := filepath .Join (tmpDir , "bkt" )
1909
+ bkt , err := filesystem .NewBucket (bktDir )
1910
+ testutil .Ok (t , err )
1911
+ defer func () { testutil .Ok (t , bkt .Close ()) }()
1912
+
1913
+ var (
1914
+ logger = log .NewNopLogger ()
1915
+ instrBkt = objstore .WithNoopInstr (bkt )
1916
+ random = rand .New (rand .NewSource (120 ))
1917
+ )
1918
+
1919
+ extLset := labels.Labels {{Name : "ext1" , Value : "1" }}
1920
+ // Inject the Thanos meta to each block in the storage.
1921
+ thanosMeta := metadata.Thanos {
1922
+ Labels : extLset .Map (),
1923
+ Downsample : metadata.ThanosDownsample {Resolution : 0 },
1924
+ Source : metadata .TestSource ,
1925
+ }
1926
+
1927
+ // Create TSDB blocks.
1928
+ head , seriesSet1 := storetestutil .CreateHeadWithSeries (t , 0 , storetestutil.HeadGenOptions {
1929
+ TSDBDir : filepath .Join (tmpDir , "0" ),
1930
+ SamplesPerSeries : 1 ,
1931
+ Series : 2 ,
1932
+ PrependLabels : extLset ,
1933
+ Random : random ,
1934
+ })
1935
+ block1 := createBlockFromHead (t , bktDir , head )
1936
+ testutil .Ok (t , head .Close ())
1937
+ head2 , seriesSet2 := storetestutil .CreateHeadWithSeries (t , 1 , storetestutil.HeadGenOptions {
1938
+ TSDBDir : filepath .Join (tmpDir , "1" ),
1939
+ SamplesPerSeries : 1 ,
1940
+ Series : 2 ,
1941
+ PrependLabels : extLset ,
1942
+ Random : random ,
1943
+ })
1944
+ block2 := createBlockFromHead (t , bktDir , head2 )
1945
+ testutil .Ok (t , head2 .Close ())
1946
+
1947
+ for _ , blockID := range []ulid.ULID {block1 , block2 } {
1948
+ _ , err := metadata .InjectThanos (logger , filepath .Join (bktDir , blockID .String ()), thanosMeta , nil )
1949
+ testutil .Ok (t , err )
1950
+ }
1951
+
1952
+ // Instance a real bucket store we'll use to query back the series.
1953
+ fetcher , err := block .NewMetaFetcher (logger , 10 , instrBkt , tmpDir , nil , nil , nil )
1954
+ testutil .Ok (tb , err )
1955
+
1956
+ indexCache , err := storecache .NewInMemoryIndexCacheWithConfig (logger , nil , storecache.InMemoryIndexCacheConfig {})
1957
+ testutil .Ok (tb , err )
1958
+
1959
+ store , err := NewBucketStore (
1960
+ logger ,
1961
+ nil ,
1962
+ instrBkt ,
1963
+ fetcher ,
1964
+ tmpDir ,
1965
+ indexCache ,
1966
+ nil ,
1967
+ 1000000 ,
1968
+ NewChunksLimiterFactory (10000 / MaxSamplesPerChunk ),
1969
+ false ,
1970
+ 10 ,
1971
+ nil ,
1972
+ false ,
1973
+ true ,
1974
+ DefaultPostingOffsetInMemorySampling ,
1975
+ true ,
1976
+ )
1977
+ testutil .Ok (tb , err )
1978
+ testutil .Ok (tb , store .SyncBlocks (context .Background ()))
1979
+
1980
+ type labelNamesValuesCase struct {
1981
+ name string
1982
+
1983
+ labelNamesReq * storepb.LabelNamesRequest
1984
+ expectedNames []string
1985
+ expectedNamesHints hintspb.LabelNamesResponseHints
1986
+
1987
+ labelValuesReq * storepb.LabelValuesRequest
1988
+ expectedValues []string
1989
+ expectedValuesHints hintspb.LabelValuesResponseHints
1990
+ }
1991
+
1992
+ testCases := []labelNamesValuesCase {
1993
+ {
1994
+ name : "querying a range containing 1 block should return 1 block in the labels hints" ,
1995
+
1996
+ labelNamesReq : & storepb.LabelNamesRequest {
1997
+ Start : 0 ,
1998
+ End : 1 ,
1999
+ },
2000
+ expectedNames : labelNamesFromSeriesSet (seriesSet1 ),
2001
+ expectedNamesHints : hintspb.LabelNamesResponseHints {
2002
+ QueriedBlocks : []hintspb.Block {
2003
+ {Id : block1 .String ()},
2004
+ },
2005
+ },
2006
+
2007
+ labelValuesReq : & storepb.LabelValuesRequest {
2008
+ Label : "__name__" ,
2009
+ Start : 0 ,
2010
+ End : 1 ,
2011
+ },
2012
+ expectedValues : []string {},
2013
+ expectedValuesHints : hintspb.LabelValuesResponseHints {
2014
+ QueriedBlocks : []hintspb.Block {
2015
+ {Id : block1 .String ()},
2016
+ },
2017
+ },
2018
+ },
2019
+ {
2020
+ name : "querying a range containing multiple blocks should return multiple blocks in the response hints" ,
2021
+
2022
+ labelNamesReq : & storepb.LabelNamesRequest {
2023
+ Start : 0 ,
2024
+ End : 3 ,
2025
+ },
2026
+ expectedNames : labelNamesFromSeriesSet (
2027
+ append (append ([]* storepb.Series {}, seriesSet1 ... ), seriesSet2 ... ),
2028
+ ),
2029
+ expectedNamesHints : hintspb.LabelNamesResponseHints {
2030
+ QueriedBlocks : []hintspb.Block {
2031
+ {Id : block1 .String ()},
2032
+ {Id : block2 .String ()},
2033
+ },
2034
+ },
2035
+
2036
+ labelValuesReq : & storepb.LabelValuesRequest {
2037
+ Label : "__name__" ,
2038
+ Start : 0 ,
2039
+ End : 3 ,
2040
+ },
2041
+ expectedValues : []string {},
2042
+ expectedValuesHints : hintspb.LabelValuesResponseHints {
2043
+ QueriedBlocks : []hintspb.Block {
2044
+ {Id : block1 .String ()},
2045
+ {Id : block2 .String ()},
2046
+ },
2047
+ },
2048
+ },
2049
+ }
2050
+
2051
+ for _ , tc := range testCases {
2052
+ t .Run (tc .name , func (t * testing.T ) {
2053
+ namesResp , err := store .LabelNames (context .Background (), tc .labelNamesReq )
2054
+ testutil .Ok (t , err )
2055
+ testutil .Equals (t , tc .expectedNames , namesResp .Names )
2056
+ var namesHints hintspb.LabelNamesResponseHints
2057
+ testutil .Ok (t , types .UnmarshalAny (namesResp .Hints , & namesHints ))
2058
+ testutil .Equals (t , tc .expectedNamesHints , namesHints )
2059
+
2060
+ valuesResp , err := store .LabelValues (context .Background (), tc .labelValuesReq )
2061
+ testutil .Ok (t , err )
2062
+ testutil .Equals (t , tc .expectedValues , valuesResp .Values )
2063
+ var valuesHints hintspb.LabelValuesResponseHints
2064
+ testutil .Ok (t , types .UnmarshalAny (valuesResp .Hints , & valuesHints ))
2065
+ testutil .Equals (t , tc .expectedValuesHints , valuesHints )
2066
+ })
2067
+ }
2068
+ }
2069
+
2070
+ func labelNamesFromSeriesSet (series []* storepb.Series ) []string {
2071
+ labelsMap := map [string ]struct {}{}
2072
+
2073
+ for _ , s := range series {
2074
+ for _ , label := range s .Labels {
2075
+ labelsMap [label .Name ] = struct {}{}
2076
+ }
2077
+ }
2078
+
2079
+ labels := make ([]string , 0 , len (labelsMap ))
2080
+ for k := range labelsMap {
2081
+ labels = append (labels , k )
2082
+ }
2083
+
2084
+ sort .Strings (labels )
2085
+ return labels
2086
+ }
0 commit comments