@@ -5060,4 +5060,111 @@ mod tests {
50605060        assert_eq ! ( search_response. failed_splits. len( ) ,  1 ) ; 
50615061        Ok ( ( ) ) 
50625062    } 
5063+ 
5064+     #[ tokio:: test]  
5065+     async  fn  test_count_from_metastore_in_contained_time_range ( )  -> anyhow:: Result < ( ) >  { 
5066+         let  search_request = quickwit_proto:: search:: SearchRequest  { 
5067+             start_timestamp :  Some ( 122_000 ) , 
5068+             end_timestamp :  Some ( 129_000 ) , 
5069+             index_id_patterns :  vec ! [ "test-index" . to_string( ) ] , 
5070+             query_ast :  serde_json:: to_string ( & QueryAst :: MatchAll ) 
5071+                 . expect ( "MatchAll should be JSON serializable." ) , 
5072+             max_hits :  0 , 
5073+             ..Default :: default ( ) 
5074+         } ; 
5075+ 
5076+         let  index_metadata = IndexMetadata :: for_test ( "test-index" ,  "ram:///test-index" ) ; 
5077+         let  index_uid = index_metadata. index_uid . clone ( ) ; 
5078+ 
5079+         let  mut  mock_metastore = MockMetastoreService :: new ( ) ; 
5080+         mock_metastore
5081+             . expect_list_indexes_metadata ( ) 
5082+             . returning ( move  |_q| { 
5083+                 Ok ( ListIndexesMetadataResponse :: for_test ( vec ! [ 
5084+                     index_metadata. clone( ) , 
5085+                 ] ) ) 
5086+             } ) ; 
5087+         mock_metastore. expect_list_splits ( ) . returning ( move  |_req| { 
5088+             let  splits = vec ! [ 
5089+                 MockSplitBuilder :: new_with_time_range( "split_before" ,  Some ( 100_000 ..=110_000 ) ) 
5090+                     . with_index_uid( & index_uid) 
5091+                     . build( ) , 
5092+                 MockSplitBuilder :: new_with_time_range( 
5093+                     "split_overlap_start" , 
5094+                     Some ( 120_000 ..=123_000 ) , 
5095+                 ) 
5096+                 . with_index_uid( & index_uid) 
5097+                 . build( ) , 
5098+                 MockSplitBuilder :: new_with_time_range( "split_overlap_end" ,  Some ( 128_000 ..=140_000 ) ) 
5099+                     . with_index_uid( & index_uid) 
5100+                     . build( ) , 
5101+                 MockSplitBuilder :: new_with_time_range( 
5102+                     "split_covering_whole" , 
5103+                     Some ( 100_000 ..=200_000 ) , 
5104+                 ) 
5105+                 . with_index_uid( & index_uid) 
5106+                 . build( ) , 
5107+                 MockSplitBuilder :: new_with_time_range( "split_inside" ,  Some ( 124_000 ..=126_000 ) ) 
5108+                     . with_index_uid( & index_uid) 
5109+                     . build( ) , 
5110+             ] ; 
5111+             let  resp = ListSplitsResponse :: try_from_splits ( splits) . unwrap ( ) ; 
5112+             Ok ( ServiceStream :: from ( vec ! [ Ok ( resp) ] ) ) 
5113+         } ) ; 
5114+ 
5115+         let  mut  mock_search = MockSearchService :: new ( ) ; 
5116+         mock_search
5117+             . expect_leaf_search ( ) 
5118+             . withf ( |leaf_search_req| { 
5119+                 let  mut  expected = HashSet :: new ( ) ; 
5120+ 
5121+                 // Notice split_inside is not included. 
5122+                 expected. insert ( "split_before" ) ; 
5123+                 expected. insert ( "split_covering_whole" ) ; 
5124+                 expected. insert ( "split_overlap_end" ) ; 
5125+                 expected. insert ( "split_overlap_start" ) ; 
5126+ 
5127+                 leaf_search_req. leaf_requests . len ( )  == 1 
5128+                     && leaf_search_req. leaf_requests [ 0 ] 
5129+                         . split_offsets 
5130+                         . iter ( ) 
5131+                         . map ( |s| s. split_id . as_str ( ) ) 
5132+                         . collect :: < HashSet < & str > > ( ) 
5133+                         == expected
5134+             } ) 
5135+             . times ( 1 ) 
5136+             . returning ( |_| { 
5137+                 Ok ( quickwit_proto:: search:: LeafSearchResponse  { 
5138+                     num_hits :  5 , 
5139+                     partial_hits :  vec ! [ ] , 
5140+                     failed_splits :  Vec :: new ( ) , 
5141+                     num_attempted_splits :  0 , 
5142+                     ..Default :: default ( ) 
5143+                 } ) 
5144+             } ) ; 
5145+         mock_search. expect_fetch_docs ( ) . returning ( |fetch_req| { 
5146+             Ok ( quickwit_proto:: search:: FetchDocsResponse  { 
5147+                 hits :  get_doc_for_fetch_req ( fetch_req) , 
5148+             } ) 
5149+         } ) ; 
5150+ 
5151+         let  searcher_pool = searcher_pool_for_test ( [ ( "127.0.0.1:1001" ,  mock_search) ] ) ; 
5152+         let  search_job_placer = SearchJobPlacer :: new ( searcher_pool) ; 
5153+         let  cluster_client = ClusterClient :: new ( search_job_placer) ; 
5154+ 
5155+         let  ctx = SearcherContext :: for_test ( ) ; 
5156+         let  resp = root_search ( 
5157+             & ctx, 
5158+             search_request, 
5159+             MetastoreServiceClient :: from_mock ( mock_metastore) , 
5160+             & cluster_client, 
5161+         ) 
5162+         . await ?; 
5163+ 
5164+         assert_eq ! ( resp. num_hits,  15 ) ; 
5165+         assert_eq ! ( resp. hits. len( ) ,  0 ) ; 
5166+         assert_eq ! ( resp. num_successful_splits,  1 ) ; 
5167+ 
5168+         Ok ( ( ) ) 
5169+     } 
50635170} 
0 commit comments