|
37 | 37 | import org.opensearch.action.search.SearchPhaseName; |
38 | 38 | import org.opensearch.action.search.SearchRequestOperationsListenerSupport; |
39 | 39 | import org.opensearch.action.search.SearchRequestStats; |
| 40 | +import org.opensearch.common.io.stream.BytesStreamOutput; |
40 | 41 | import org.opensearch.common.settings.ClusterSettings; |
41 | 42 | import org.opensearch.common.settings.Settings; |
42 | 43 | import org.opensearch.index.search.stats.SearchStats.Stats; |
43 | 44 | import org.opensearch.test.OpenSearchTestCase; |
| 45 | +import org.junit.Assert; |
44 | 46 |
|
45 | 47 | import java.util.HashMap; |
46 | 48 | import java.util.Map; |
@@ -162,4 +164,45 @@ private static void assertStats(Stats stats, long equalTo) { |
162 | 164 | // avg_concurrency is not summed up across stats |
163 | 165 | assertEquals(1, stats.getConcurrentAvgSliceCount(), 0); |
164 | 166 | } |
| 167 | + |
| 168 | + public void testNegativeRequestStats() throws Exception { |
| 169 | + SearchStats searchStats = new SearchStats(new Stats(), 0, new HashMap<>()); |
| 170 | + |
| 171 | + long paramValue = randomIntBetween(2, 50); |
| 172 | + |
| 173 | + // Testing for request stats |
| 174 | + ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); |
| 175 | + SearchRequestStats testRequestStats = new SearchRequestStats(clusterSettings); |
| 176 | + SearchPhaseContext ctx = mock(SearchPhaseContext.class); |
| 177 | + for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) { |
| 178 | + SearchPhase mockSearchPhase = mock(SearchPhase.class); |
| 179 | + when(ctx.getCurrentPhase()).thenReturn(mockSearchPhase); |
| 180 | + when(mockSearchPhase.getStartTimeInNanos()).thenReturn(System.nanoTime() - TimeUnit.SECONDS.toNanos(paramValue)); |
| 181 | + when(mockSearchPhase.getSearchPhaseNameOptional()).thenReturn(Optional.ofNullable(searchPhaseName)); |
| 182 | + for (int iterator = 0; iterator < paramValue; iterator++) { |
| 183 | + onPhaseStart(testRequestStats, ctx); |
| 184 | + onPhaseEnd(testRequestStats, ctx); |
| 185 | + onPhaseEnd(testRequestStats, ctx); // call onPhaseEnd() twice to make 'current' negative |
| 186 | + } |
| 187 | + } |
| 188 | + searchStats.setSearchRequestStats(testRequestStats); |
| 189 | + for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) { |
| 190 | + Assert.assertNotNull(searchStats.getTotal().getRequestStatsLongHolder()); |
| 191 | + assertEquals( |
| 192 | + -1 * paramValue, // current is negative, equals -1 * paramValue (num loop iterations) |
| 193 | + searchStats.getTotal().getRequestStatsLongHolder().getRequestStatsHolder().get(searchPhaseName.getName()).current |
| 194 | + ); |
| 195 | + assertEquals( |
| 196 | + 2 * paramValue, |
| 197 | + searchStats.getTotal().getRequestStatsLongHolder().getRequestStatsHolder().get(searchPhaseName.getName()).total |
| 198 | + ); |
| 199 | + assertThat( |
| 200 | + searchStats.getTotal().getRequestStatsLongHolder().getRequestStatsHolder().get(searchPhaseName.getName()).timeInMillis, |
| 201 | + greaterThanOrEqualTo(paramValue) |
| 202 | + ); |
| 203 | + } |
| 204 | + |
| 205 | + // Ensure writeTo() does not throw error with negative 'current' |
| 206 | + searchStats.writeTo(new BytesStreamOutput(10)); |
| 207 | + } |
165 | 208 | } |
0 commit comments