@@ -136,7 +136,6 @@ private static IndexSettingsAnalysis toAnalysis(String settingsJson) {
136136
137137 private long originalBulkInitialBackoffMs ;
138138 private long originalProbeInitialBackoffMs ;
139- private long originalCountProbeInitialBackoffMs ;
140139 private long originalSentinelCleanupInitialBackoffMs ;
141140
142141 @ BeforeEach
@@ -147,8 +146,6 @@ public void setUp() {
147146 OpenSearchManagerImpl .BULK_INDEX_INITIAL_BACKOFF_MS = 1L ;
148147 originalProbeInitialBackoffMs = OpenSearchManagerImpl .INDEX_WRITABLE_INITIAL_BACKOFF_MS ;
149148 OpenSearchManagerImpl .INDEX_WRITABLE_INITIAL_BACKOFF_MS = 1L ;
150- originalCountProbeInitialBackoffMs = OpenSearchManagerImpl .COUNT_PROBE_INITIAL_BACKOFF_MS ;
151- OpenSearchManagerImpl .COUNT_PROBE_INITIAL_BACKOFF_MS = 1L ;
152149 originalSentinelCleanupInitialBackoffMs = OpenSearchManagerImpl .SENTINEL_CLEANUP_INITIAL_BACKOFF_MS ;
153150 OpenSearchManagerImpl .SENTINEL_CLEANUP_INITIAL_BACKOFF_MS = 1L ;
154151 }
@@ -157,7 +154,6 @@ public void setUp() {
157154 public void tearDown () {
158155 OpenSearchManagerImpl .BULK_INDEX_INITIAL_BACKOFF_MS = originalBulkInitialBackoffMs ;
159156 OpenSearchManagerImpl .INDEX_WRITABLE_INITIAL_BACKOFF_MS = originalProbeInitialBackoffMs ;
160- OpenSearchManagerImpl .COUNT_PROBE_INITIAL_BACKOFF_MS = originalCountProbeInitialBackoffMs ;
161157 OpenSearchManagerImpl .SENTINEL_CLEANUP_INITIAL_BACKOFF_MS = originalSentinelCleanupInitialBackoffMs ;
162158 }
163159
@@ -1718,117 +1714,6 @@ public void testWaitForIndexWritableSentinelCleanupRetriesAndSucceeds() throws E
17181714 verify (openSearchClient , times (2 )).delete (argThat ((DeleteRequest req ) -> req != null ));
17191715 }
17201716
1721- // --- waitForDocumentCount ---
1722-
1723- @ Test
1724- public void testWaitForDocumentCountWithImmediateMatchReturns () throws Exception {
1725- // Happy path: AOSS reports the expected count on the first attempt; no retry, no log noise.
1726- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1727- .thenReturn (org .opensearch .client .opensearch .core .CountResponse .of (b -> b
1728- .count (5L )
1729- .shards (s -> s .total (1 ).successful (1 ).failed (0 ))));
1730-
1731- // call under test
1732- manager .waitForDocumentCount ("search-index-syn1" , 5L );
1733-
1734- verify (openSearchClient , times (1 ))
1735- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1736- }
1737-
1738- @ Test
1739- public void testWaitForDocumentCountConvergesAfterUnderCount () throws Exception {
1740- // AOSS is eventually consistent: the first probe sees fewer documents than were
1741- // bulk-indexed; the second sees the full count and returns.
1742- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1743- .thenReturn (countResponse (2L ))
1744- .thenReturn (countResponse (5L ));
1745-
1746- // call under test
1747- manager .waitForDocumentCount ("search-index-syn1" , 5L );
1748-
1749- verify (openSearchClient , times (2 ))
1750- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1751- }
1752-
1753- @ Test
1754- public void testWaitForDocumentCountTreatsExcessAsConverged () throws Exception {
1755- // >= rather than == so a leftover readiness-probe sentinel cannot strand convergence
1756- // one short. An excess count is therefore a successful return, not a retry.
1757- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1758- .thenReturn (countResponse (6L ));
1759-
1760- // call under test
1761- manager .waitForDocumentCount ("search-index-syn1" , 5L );
1762-
1763- verify (openSearchClient , times (1 ))
1764- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1765- }
1766-
1767- @ Test
1768- public void testWaitForDocumentCountExhaustsRetriesAndThrowsRecoverableMessageException () throws Exception {
1769- // Persistent under-count: every attempt sees fewer documents than expected. The probe
1770- // must throw RecoverableMessageException so the lifecycle worker re-queues the message
1771- // without writing FAILED — convergence is transient by definition.
1772- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1773- .thenReturn (countResponse (2L ));
1774-
1775- // call under test
1776- RecoverableMessageException ex = assertThrows (RecoverableMessageException .class ,
1777- () -> manager .waitForDocumentCount ("search-index-syn1" , 5L ));
1778-
1779- assertTrue (ex .getMessage ().contains ("did not converge" ), ex .getMessage ());
1780- assertTrue (ex .getMessage ().contains ("2 of 5" ), ex .getMessage ());
1781- verify (openSearchClient , times (OpenSearchManagerImpl .COUNT_PROBE_MAX_RETRIES ))
1782- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1783- }
1784-
1785- @ Test
1786- public void testWaitForDocumentCountWithIOExceptionExhaustsRetries () throws Exception {
1787- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1788- .thenThrow (new IOException ("connection reset" ));
1789-
1790- // call under test
1791- assertThrows (RecoverableMessageException .class ,
1792- () -> manager .waitForDocumentCount ("search-index-syn1" , 5L ));
1793-
1794- verify (openSearchClient , times (OpenSearchManagerImpl .COUNT_PROBE_MAX_RETRIES ))
1795- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1796- }
1797-
1798- @ Test
1799- public void testWaitForDocumentCountWithOpenSearchExceptionExhaustsRetries () throws Exception {
1800- // AOSS may briefly return index_not_found_exception (or any other transient error) from
1801- // _count while shards are still propagating the freshly-written documents.
1802- ErrorResponse notFound = ErrorResponse .of (er -> er
1803- .error (ErrorCause .of (e -> e .type ("index_not_found_exception" ).reason ("no such index" )))
1804- .status (404 ));
1805- when (openSearchClient .count (any (org .opensearch .client .opensearch .core .CountRequest .class )))
1806- .thenThrow (new OpenSearchException (notFound ));
1807-
1808- // call under test
1809- assertThrows (RecoverableMessageException .class ,
1810- () -> manager .waitForDocumentCount ("search-index-syn1" , 5L ));
1811-
1812- verify (openSearchClient , times (OpenSearchManagerImpl .COUNT_PROBE_MAX_RETRIES ))
1813- .count (any (org .opensearch .client .opensearch .core .CountRequest .class ));
1814- }
1815-
1816- @ Test
1817- public void testWaitForDocumentCountWithZeroExpectedShortCircuits () throws Exception {
1818- // An empty SearchIndex needs no probe — _count would just return 0 and we'd skip the
1819- // retry path anyway. Avoid the round-trip entirely.
1820- // call under test
1821- manager .waitForDocumentCount ("search-index-syn1" , 0L );
1822-
1823- verifyZeroInteractions (openSearchClient );
1824- }
1825-
1826- private static org .opensearch .client .opensearch .core .CountResponse countResponse (long count ) {
1827- return org .opensearch .client .opensearch .core .CountResponse .of (b -> b
1828- .count (count )
1829- .shards (s -> s .total (1 ).successful (1 ).failed (0 )));
1830- }
1831-
18321717 // --- per-document fallback on partial batch failure ---
18331718
18341719 @ Test
0 commit comments