@@ -94,7 +94,7 @@ func TestMicroServicesIngestQuery(t *testing.T) {
9494 "-common.compactor-address=" + tCompactor .HTTPURL (),
9595 "-querier.per-request-limits-enabled=true" ,
9696 "-frontend.encoding=protobuf" ,
97- "-querier.shard-aggregations=quantile_over_time" ,
97+ "-querier.shard-aggregations=quantile_over_time,approx_topk " ,
9898 "-frontend.tail-proxy-url=" + tQuerier .HTTPURL (),
9999 )
100100 )
@@ -784,6 +784,115 @@ func TestOTLPLogsIngestQuery(t *testing.T) {
784784 })
785785}
786786
787+ func TestProbabilisticQuery (t * testing.T ) {
788+ clu := cluster .New (nil , cluster .SchemaWithTSDBAndTSDB , func (c * cluster.Cluster ) {
789+ c .SetSchemaVer ("v13" )
790+ })
791+ defer func () {
792+ assert .NoError (t , clu .Cleanup ())
793+ }()
794+
795+ // run initially the compactor, indexgateway, and distributor.
796+ var (
797+ tCompactor = clu .AddComponent (
798+ "compactor" ,
799+ "-target=compactor" ,
800+ "-compactor.compaction-interval=1s" ,
801+ "-compactor.retention-delete-delay=1s" ,
802+ // By default, a minute is added to the delete request start time. This compensates for that.
803+ "-compactor.delete-request-cancel-period=-60s" ,
804+ "-compactor.deletion-mode=filter-and-delete" ,
805+ )
806+ tIndexGateway = clu .AddComponent (
807+ "index-gateway" ,
808+ "-target=index-gateway" ,
809+ )
810+ tDistributor = clu .AddComponent (
811+ "distributor" ,
812+ "-target=distributor" ,
813+ )
814+ )
815+ require .NoError (t , clu .Run ())
816+
817+ // then, run only the ingester and query scheduler.
818+ var (
819+ tIngester = clu .AddComponent (
820+ "ingester" ,
821+ "-target=ingester" ,
822+ "-boltdb.shipper.index-gateway-client.server-address=" + tIndexGateway .GRPCURL (),
823+ )
824+ tQueryScheduler = clu .AddComponent (
825+ "query-scheduler" ,
826+ "-target=query-scheduler" ,
827+ "-query-scheduler.use-scheduler-ring=false" ,
828+ "-boltdb.shipper.index-gateway-client.server-address=" + tIndexGateway .GRPCURL (),
829+ )
830+ )
831+ require .NoError (t , clu .Run ())
832+
833+ // the run querier.
834+ var (
835+ tQuerier = clu .AddComponent (
836+ "querier" ,
837+ "-target=querier" ,
838+ "-querier.scheduler-address=" + tQueryScheduler .GRPCURL (),
839+ "-boltdb.shipper.index-gateway-client.server-address=" + tIndexGateway .GRPCURL (),
840+ "-common.compactor-address=" + tCompactor .HTTPURL (),
841+ )
842+ )
843+ require .NoError (t , clu .Run ())
844+
845+ // finally, run the query-frontend.
846+ var (
847+ tQueryFrontend = clu .AddComponent (
848+ "query-frontend" ,
849+ "-target=query-frontend" ,
850+ "-frontend.scheduler-address=" + tQueryScheduler .GRPCURL (),
851+ "-boltdb.shipper.index-gateway-client.server-address=" + tIndexGateway .GRPCURL (),
852+ "-common.compactor-address=" + tCompactor .HTTPURL (),
853+ "-querier.per-request-limits-enabled=true" ,
854+ "-frontend.encoding=protobuf" ,
855+ "-querier.shard-aggregations=quantile_over_time,approx_topk" ,
856+ "-frontend.tail-proxy-url=" + tQuerier .HTTPURL (),
857+ )
858+ )
859+ require .NoError (t , clu .Run ())
860+
861+ tenantID := randStringRunes ()
862+
863+ now := time .Now ()
864+ cliDistributor := client .New (tenantID , "" , tDistributor .HTTPURL ())
865+ cliDistributor .Now = now
866+ cliIngester := client .New (tenantID , "" , tIngester .HTTPURL ())
867+ cliIngester .Now = now
868+ cliQueryFrontend := client .New (tenantID , "" , tQueryFrontend .HTTPURL ())
869+ cliQueryFrontend .Now = now
870+
871+ t .Run ("ingest-logs" , func (t * testing.T ) {
872+ // ingest some log lines
873+ require .NoError (t , cliDistributor .PushLogLine ("lineA" , now .Add (- 45 * time .Minute ), nil , map [string ]string {"job" : "one" }))
874+ require .NoError (t , cliDistributor .PushLogLine ("lineB" , now .Add (- 45 * time .Minute ), nil , map [string ]string {"job" : "one" }))
875+
876+ require .NoError (t , cliDistributor .PushLogLine ("lineC" , now , nil , map [string ]string {"job" : "one" }))
877+ require .NoError (t , cliDistributor .PushLogLine ("lineD" , now , nil , map [string ]string {"job" : "two" }))
878+ })
879+
880+ t .Run ("query" , func (t * testing.T ) {
881+ resp , err := cliQueryFrontend .RunQuery (context .Background (), `approx_topk(1, count_over_time({job=~".+"}[1h]))` )
882+ require .NoError (t , err )
883+ assert .Equal (t , "vector" , resp .Data .ResultType )
884+
885+ var values []string
886+ var labels []string
887+ for _ , value := range resp .Data .Vector {
888+ values = append (values , value .Value )
889+ labels = append (labels , value .Metric ["job" ])
890+ }
891+ assert .ElementsMatch (t , []string {"3" }, values )
892+ assert .ElementsMatch (t , []string {"one" }, labels )
893+ })
894+ }
895+
787896func TestCategorizedLabels (t * testing.T ) {
788897 clu := cluster .New (nil , cluster .SchemaWithTSDB , func (c * cluster.Cluster ) {
789898 c .SetSchemaVer ("v13" )
0 commit comments