32
32
33
33
package org .opensearch .search .profile .query ;
34
34
35
+ import com .carrotsearch .randomizedtesting .annotations .ParametersFactory ;
36
+
35
37
import org .apache .lucene .tests .util .English ;
36
38
import org .opensearch .action .index .IndexRequestBuilder ;
37
39
import org .opensearch .action .search .MultiSearchResponse ;
40
42
import org .opensearch .action .search .SearchType ;
41
43
import org .opensearch .action .search .ShardSearchFailure ;
42
44
import org .opensearch .common .settings .Settings ;
45
+ import org .opensearch .common .util .FeatureFlags ;
43
46
import org .opensearch .index .query .QueryBuilder ;
44
47
import org .opensearch .index .query .QueryBuilders ;
45
48
import org .opensearch .search .SearchHit ;
46
49
import org .opensearch .search .profile .ProfileResult ;
47
50
import org .opensearch .search .profile .ProfileShardResult ;
48
51
import org .opensearch .search .sort .SortOrder ;
49
- import org .opensearch .test .OpenSearchIntegTestCase ;
52
+ import org .opensearch .test .ParameterizedOpenSearchIntegTestCase ;
50
53
51
54
import java .util .Arrays ;
55
+ import java .util .Collection ;
52
56
import java .util .HashSet ;
53
57
import java .util .List ;
54
58
import java .util .Map ;
55
59
import java .util .Set ;
56
60
61
+ import static org .opensearch .search .SearchService .CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING ;
57
62
import static org .opensearch .search .profile .query .RandomQueryGenerator .randomQueryBuilder ;
58
63
import static org .hamcrest .Matchers .emptyOrNullString ;
59
64
import static org .hamcrest .Matchers .equalTo ;
60
65
import static org .hamcrest .Matchers .greaterThan ;
61
66
import static org .hamcrest .Matchers .greaterThanOrEqualTo ;
62
67
import static org .hamcrest .Matchers .is ;
63
68
import static org .hamcrest .Matchers .not ;
69
+ import static org .hamcrest .Matchers .nullValue ;
70
+
71
+ public class QueryProfilerIT extends ParameterizedOpenSearchIntegTestCase {
72
+ private final boolean concurrentSearchEnabled ;
73
+ private static final String MAX_PREFIX = "max_" ;
74
+ private static final String MIN_PREFIX = "min_" ;
75
+ private static final String AVG_PREFIX = "avg_" ;
76
+ private static final String TIMING_TYPE_COUNT_SUFFIX = "_count" ;
77
+
78
+ public QueryProfilerIT (Settings settings , boolean concurrentSearchEnabled ) {
79
+ super (settings );
80
+ this .concurrentSearchEnabled = concurrentSearchEnabled ;
81
+ }
64
82
65
- public class QueryProfilerIT extends OpenSearchIntegTestCase {
83
+ @ ParametersFactory
84
+ public static Collection <Object []> parameters () {
85
+ return Arrays .asList (
86
+ new Object [] { Settings .builder ().put (CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING .getKey (), false ).build (), false },
87
+ new Object [] { Settings .builder ().put (CLUSTER_CONCURRENT_SEGMENT_SEARCH_SETTING .getKey (), true ).build (), true }
88
+ );
89
+ }
90
+
91
+ @ Override
92
+ protected Settings featureFlagSettings () {
93
+ return Settings .builder ().put (super .featureFlagSettings ()).put (FeatureFlags .CONCURRENT_SEGMENT_SEARCH , "true" ).build ();
94
+ }
66
95
67
96
/**
68
97
* This test simply checks to make sure nothing crashes. Test indexes 100-150 documents,
@@ -229,6 +258,7 @@ public void testSimpleMatch() throws Exception {
229
258
assertEquals (result .getLuceneDescription (), "field1:one" );
230
259
assertThat (result .getTime (), greaterThan (0L ));
231
260
assertNotNull (result .getTimeBreakdown ());
261
+ assertQueryProfileResult (result );
232
262
}
233
263
234
264
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -271,6 +301,7 @@ public void testBool() throws Exception {
271
301
assertThat (result .getTime (), greaterThan (0L ));
272
302
assertNotNull (result .getTimeBreakdown ());
273
303
assertEquals (result .getProfiledChildren ().size (), 2 );
304
+ assertQueryProfileResult (result );
274
305
275
306
// Check the children
276
307
List <ProfileResult > children = result .getProfiledChildren ();
@@ -282,12 +313,14 @@ public void testBool() throws Exception {
282
313
assertThat (childProfile .getTime (), greaterThan (0L ));
283
314
assertNotNull (childProfile .getTimeBreakdown ());
284
315
assertEquals (childProfile .getProfiledChildren ().size (), 0 );
316
+ assertQueryProfileResult (childProfile );
285
317
286
318
childProfile = children .get (1 );
287
319
assertEquals (childProfile .getQueryName (), "TermQuery" );
288
320
assertEquals (childProfile .getLuceneDescription (), "field1:two" );
289
321
assertThat (childProfile .getTime (), greaterThan (0L ));
290
322
assertNotNull (childProfile .getTimeBreakdown ());
323
+ assertQueryProfileResult (childProfile );
291
324
}
292
325
293
326
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -330,6 +363,7 @@ public void testEmptyBool() throws Exception {
330
363
assertNotNull (result .getLuceneDescription ());
331
364
assertThat (result .getTime (), greaterThan (0L ));
332
365
assertNotNull (result .getTimeBreakdown ());
366
+ assertQueryProfileResult (result );
333
367
}
334
368
335
369
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -375,6 +409,7 @@ public void testCollapsingBool() throws Exception {
375
409
assertNotNull (result .getLuceneDescription ());
376
410
assertThat (result .getTime (), greaterThan (0L ));
377
411
assertNotNull (result .getTimeBreakdown ());
412
+ assertQueryProfileResult (result );
378
413
}
379
414
380
415
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -415,6 +450,90 @@ public void testBoosting() throws Exception {
415
450
assertNotNull (result .getLuceneDescription ());
416
451
assertThat (result .getTime (), greaterThan (0L ));
417
452
assertNotNull (result .getTimeBreakdown ());
453
+ assertQueryProfileResult (result );
454
+ }
455
+
456
+ CollectorResult result = searchProfiles .getCollectorResult ();
457
+ assertThat (result .getName (), is (not (emptyOrNullString ())));
458
+ assertThat (result .getTime (), greaterThan (0L ));
459
+ }
460
+ }
461
+ }
462
+
463
+ public void testSearchLeafForItsLeavesAndRewriteQuery () throws Exception {
464
+ createIndex ("test" );
465
+ ensureGreen ();
466
+
467
+ int numDocs = 122 ;
468
+ IndexRequestBuilder [] docs = new IndexRequestBuilder [numDocs ];
469
+ for (int i = 0 ; i < numDocs ; i ++) {
470
+ docs [i ] = client ().prepareIndex ("test" ).setId (String .valueOf (i )).setSource ("field1" , English .intToEnglish (i ), "field2" , i );
471
+ }
472
+
473
+ List <String > terms = Arrays .asList ("zero" , "zero" , "one" );
474
+
475
+ indexRandom (true , docs );
476
+
477
+ refresh ();
478
+
479
+ QueryBuilder q = QueryBuilders .boostingQuery (
480
+ QueryBuilders .idsQuery ().addIds (String .valueOf (randomInt ()), String .valueOf (randomInt ())),
481
+ QueryBuilders .termsQuery ("field1" , terms )
482
+ ).boost (randomFloat ()).negativeBoost (randomFloat ());
483
+ logger .info ("Query: {}" , q );
484
+
485
+ SearchResponse resp = client ().prepareSearch ()
486
+ .setQuery (q )
487
+ .setTrackTotalHits (true )
488
+ .setProfile (true )
489
+ .setSearchType (SearchType .QUERY_THEN_FETCH )
490
+ .get ();
491
+
492
+ assertNotNull ("Profile response element should not be null" , resp .getProfileResults ());
493
+ assertThat ("Profile response should not be an empty array" , resp .getProfileResults ().size (), not (0 ));
494
+
495
+ for (Map .Entry <String , ProfileShardResult > shardResult : resp .getProfileResults ().entrySet ()) {
496
+ assertThat (shardResult .getValue ().getNetworkTime ().getInboundNetworkTime (), greaterThanOrEqualTo (0L ));
497
+ assertThat (shardResult .getValue ().getNetworkTime ().getOutboundNetworkTime (), greaterThanOrEqualTo (0L ));
498
+ for (QueryProfileShardResult searchProfiles : shardResult .getValue ().getQueryProfileResults ()) {
499
+ List <ProfileResult > results = searchProfiles .getQueryResults ();
500
+ for (ProfileResult result : results ) {
501
+ assertNotNull (result .getQueryName ());
502
+ assertNotNull (result .getLuceneDescription ());
503
+ assertThat (result .getTime (), greaterThan (0L ));
504
+ Map <String , Long > breakdown = result .getTimeBreakdown ();
505
+ Long maxSliceTime = result .getMaxSliceTime ();
506
+ Long minSliceTime = result .getMinSliceTime ();
507
+ Long avgSliceTime = result .getAvgSliceTime ();
508
+ if (concurrentSearchEnabled && results .get (0 ).equals (result )) {
509
+ assertNotNull (maxSliceTime );
510
+ assertNotNull (minSliceTime );
511
+ assertNotNull (avgSliceTime );
512
+ assertThat (breakdown .size (), equalTo (66 ));
513
+ for (QueryTimingType queryTimingType : QueryTimingType .values ()) {
514
+ if (queryTimingType != QueryTimingType .CREATE_WEIGHT ) {
515
+ String maxTimingType = MAX_PREFIX + queryTimingType ;
516
+ String minTimingType = MIN_PREFIX + queryTimingType ;
517
+ String avgTimingType = AVG_PREFIX + queryTimingType ;
518
+ assertNotNull (breakdown .get (maxTimingType ));
519
+ assertNotNull (breakdown .get (minTimingType ));
520
+ assertNotNull (breakdown .get (avgTimingType ));
521
+ assertNotNull (breakdown .get (maxTimingType + TIMING_TYPE_COUNT_SUFFIX ));
522
+ assertNotNull (breakdown .get (minTimingType + TIMING_TYPE_COUNT_SUFFIX ));
523
+ assertNotNull (breakdown .get (avgTimingType + TIMING_TYPE_COUNT_SUFFIX ));
524
+ }
525
+ }
526
+ } else if (concurrentSearchEnabled ) {
527
+ assertThat (maxSliceTime , equalTo (0L ));
528
+ assertThat (minSliceTime , equalTo (0L ));
529
+ assertThat (avgSliceTime , equalTo (0L ));
530
+ assertThat (breakdown .size (), equalTo (27 ));
531
+ } else {
532
+ assertThat (maxSliceTime , is (nullValue ()));
533
+ assertThat (minSliceTime , is (nullValue ()));
534
+ assertThat (avgSliceTime , is (nullValue ()));
535
+ assertThat (breakdown .size (), equalTo (27 ));
536
+ }
418
537
}
419
538
420
539
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -455,6 +574,7 @@ public void testDisMaxRange() throws Exception {
455
574
assertNotNull (result .getLuceneDescription ());
456
575
assertThat (result .getTime (), greaterThan (0L ));
457
576
assertNotNull (result .getTimeBreakdown ());
577
+ assertQueryProfileResult (result );
458
578
}
459
579
460
580
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -494,6 +614,7 @@ public void testRange() throws Exception {
494
614
assertNotNull (result .getLuceneDescription ());
495
615
assertThat (result .getTime (), greaterThan (0L ));
496
616
assertNotNull (result .getTimeBreakdown ());
617
+ assertQueryProfileResult (result );
497
618
}
498
619
499
620
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -547,6 +668,7 @@ public void testPhrase() throws Exception {
547
668
assertNotNull (result .getLuceneDescription ());
548
669
assertThat (result .getTime (), greaterThan (0L ));
549
670
assertNotNull (result .getTimeBreakdown ());
671
+ assertQueryProfileResult (result );
550
672
}
551
673
552
674
CollectorResult result = searchProfiles .getCollectorResult ();
@@ -579,4 +701,35 @@ public void testNoProfile() throws Exception {
579
701
assertThat ("Profile response element should be an empty map" , resp .getProfileResults ().size (), equalTo (0 ));
580
702
}
581
703
704
+ private void assertQueryProfileResult (ProfileResult result ) {
705
+ Map <String , Long > breakdown = result .getTimeBreakdown ();
706
+ Long maxSliceTime = result .getMaxSliceTime ();
707
+ Long minSliceTime = result .getMinSliceTime ();
708
+ Long avgSliceTime = result .getAvgSliceTime ();
709
+ if (concurrentSearchEnabled ) {
710
+ assertNotNull (maxSliceTime );
711
+ assertNotNull (minSliceTime );
712
+ assertNotNull (avgSliceTime );
713
+ assertThat (breakdown .size (), equalTo (66 ));
714
+ for (QueryTimingType queryTimingType : QueryTimingType .values ()) {
715
+ if (queryTimingType != QueryTimingType .CREATE_WEIGHT ) {
716
+ String maxTimingType = MAX_PREFIX + queryTimingType ;
717
+ String minTimingType = MIN_PREFIX + queryTimingType ;
718
+ String avgTimingType = AVG_PREFIX + queryTimingType ;
719
+ assertNotNull (breakdown .get (maxTimingType ));
720
+ assertNotNull (breakdown .get (minTimingType ));
721
+ assertNotNull (breakdown .get (avgTimingType ));
722
+ assertNotNull (breakdown .get (maxTimingType + TIMING_TYPE_COUNT_SUFFIX ));
723
+ assertNotNull (breakdown .get (minTimingType + TIMING_TYPE_COUNT_SUFFIX ));
724
+ assertNotNull (breakdown .get (avgTimingType + TIMING_TYPE_COUNT_SUFFIX ));
725
+ }
726
+ }
727
+ } else {
728
+ assertThat (maxSliceTime , is (nullValue ()));
729
+ assertThat (minSliceTime , is (nullValue ()));
730
+ assertThat (avgSliceTime , is (nullValue ()));
731
+ assertThat (breakdown .size (), equalTo (27 ));
732
+ }
733
+ }
734
+
582
735
}
0 commit comments