@@ -153,13 +153,24 @@ public void testDelayedShareFetchTryCompleteReturnsFalseDueToNonAcquirablePartit
153
153
when (sp0 .canAcquireRecords ()).thenReturn (false );
154
154
when (sp1 .canAcquireRecords ()).thenReturn (false );
155
155
156
+ Partition p0 = mock (Partition .class );
157
+ when (p0 .isLeader ()).thenReturn (true );
158
+
159
+ Partition p1 = mock (Partition .class );
160
+ when (p1 .isLeader ()).thenReturn (true );
161
+
162
+ ReplicaManager replicaManager = mock (ReplicaManager .class );
163
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
164
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
165
+
156
166
ShareGroupMetrics shareGroupMetrics = new ShareGroupMetrics (new MockTime ());
157
167
Uuid fetchId = Uuid .randomUuid ();
158
168
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
159
169
.withShareFetchData (shareFetch )
160
170
.withSharePartitions (sharePartitions )
161
171
.withShareGroupMetrics (shareGroupMetrics )
162
172
.withFetchId (fetchId )
173
+ .withReplicaManager (replicaManager )
163
174
.build ());
164
175
165
176
when (sp0 .maybeAcquireFetchLock (fetchId )).thenReturn (true );
@@ -218,6 +229,15 @@ public void testTryCompleteWhenMinBytesNotSatisfiedOnFirstFetch() {
218
229
219
230
PartitionMaxBytesStrategy partitionMaxBytesStrategy = mockPartitionMaxBytes (Set .of (tp0 ));
220
231
232
+ Partition p0 = mock (Partition .class );
233
+ when (p0 .isLeader ()).thenReturn (true );
234
+
235
+ Partition p1 = mock (Partition .class );
236
+ when (p1 .isLeader ()).thenReturn (true );
237
+
238
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
239
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
240
+
221
241
Time time = mock (Time .class );
222
242
when (time .hiResClockMs ()).thenReturn (100L ).thenReturn (110L );
223
243
ShareGroupMetrics shareGroupMetrics = new ShareGroupMetrics (time );
@@ -287,6 +307,15 @@ public void testTryCompleteWhenMinBytesNotSatisfiedOnSubsequentFetch() {
287
307
mockTopicIdPartitionFetchBytes (replicaManager , tp0 , hwmOffsetMetadata );
288
308
BiConsumer <SharePartitionKey , Throwable > exceptionHandler = mockExceptionHandler ();
289
309
310
+ Partition p0 = mock (Partition .class );
311
+ when (p0 .isLeader ()).thenReturn (true );
312
+
313
+ Partition p1 = mock (Partition .class );
314
+ when (p1 .isLeader ()).thenReturn (true );
315
+
316
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
317
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
318
+
290
319
Uuid fetchId = Uuid .randomUuid ();
291
320
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
292
321
.withShareFetchData (shareFetch )
@@ -580,6 +609,19 @@ public void testForceCompleteTriggersDelayedActionsQueue() {
580
609
List <DelayedOperationKey > delayedShareFetchWatchKeys = new ArrayList <>();
581
610
topicIdPartitions1 .forEach (topicIdPartition -> delayedShareFetchWatchKeys .add (new DelayedShareFetchGroupKey (groupId , topicIdPartition .topicId (), topicIdPartition .partition ())));
582
611
612
+ Partition p0 = mock (Partition .class );
613
+ when (p0 .isLeader ()).thenReturn (true );
614
+
615
+ Partition p1 = mock (Partition .class );
616
+ when (p1 .isLeader ()).thenReturn (true );
617
+
618
+ Partition p2 = mock (Partition .class );
619
+ when (p2 .isLeader ()).thenReturn (true );
620
+
621
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
622
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
623
+ when (replicaManager .getPartitionOrException (tp2 .topicPartition ())).thenReturn (p2 );
624
+
583
625
Uuid fetchId1 = Uuid .randomUuid ();
584
626
DelayedShareFetch delayedShareFetch1 = DelayedShareFetchTest .DelayedShareFetchBuilder .builder ()
585
627
.withShareFetchData (shareFetch1 )
@@ -737,6 +779,12 @@ public void testExceptionInMinBytesCalculation() {
737
779
when (time .hiResClockMs ()).thenReturn (100L ).thenReturn (110L ).thenReturn (170L );
738
780
ShareGroupMetrics shareGroupMetrics = new ShareGroupMetrics (time );
739
781
Uuid fetchId = Uuid .randomUuid ();
782
+
783
+ Partition p0 = mock (Partition .class );
784
+ when (p0 .isLeader ()).thenReturn (true );
785
+
786
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
787
+
740
788
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
741
789
.withShareFetchData (shareFetch )
742
790
.withSharePartitions (sharePartitions )
@@ -881,10 +929,18 @@ public void testLocksReleasedAcquireException() {
881
929
BROKER_TOPIC_STATS );
882
930
883
931
Uuid fetchId = Uuid .randomUuid ();
932
+
933
+ Partition p0 = mock (Partition .class );
934
+ when (p0 .isLeader ()).thenReturn (true );
935
+
936
+ ReplicaManager replicaManager = mock (ReplicaManager .class );
937
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
938
+
884
939
DelayedShareFetch delayedShareFetch = DelayedShareFetchTest .DelayedShareFetchBuilder .builder ()
885
940
.withShareFetchData (shareFetch )
886
941
.withSharePartitions (sharePartitions )
887
942
.withFetchId (fetchId )
943
+ .withReplicaManager (replicaManager )
888
944
.build ();
889
945
890
946
when (sp0 .maybeAcquireFetchLock (fetchId )).thenReturn (true );
@@ -1263,6 +1319,19 @@ public void testRemoteStorageFetchTryCompleteReturnsFalse() {
1263
1319
when (remoteLogManager .asyncRead (any (), any ())).thenReturn (mock (Future .class ));
1264
1320
when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1265
1321
1322
+ Partition p0 = mock (Partition .class );
1323
+ when (p0 .isLeader ()).thenReturn (true );
1324
+
1325
+ Partition p1 = mock (Partition .class );
1326
+ when (p1 .isLeader ()).thenReturn (true );
1327
+
1328
+ Partition p2 = mock (Partition .class );
1329
+ when (p2 .isLeader ()).thenReturn (true );
1330
+
1331
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1332
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
1333
+ when (replicaManager .getPartitionOrException (tp2 .topicPartition ())).thenReturn (p2 );
1334
+
1266
1335
Uuid fetchId = Uuid .randomUuid ();
1267
1336
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1268
1337
.withShareFetchData (shareFetch )
@@ -1288,6 +1357,70 @@ public void testRemoteStorageFetchTryCompleteReturnsFalse() {
1288
1357
delayedShareFetch .lock ().unlock ();
1289
1358
}
1290
1359
1360
+ @ Test
1361
+ public void testRemoteStorageFetchPartitionLeaderChanged () {
1362
+ ReplicaManager replicaManager = mock (ReplicaManager .class );
1363
+ TopicIdPartition tp0 = new TopicIdPartition (Uuid .randomUuid (), new TopicPartition ("foo" , 0 ));
1364
+
1365
+ SharePartition sp0 = mock (SharePartition .class );
1366
+
1367
+ when (sp0 .canAcquireRecords ()).thenReturn (true );
1368
+
1369
+ LinkedHashMap <TopicIdPartition , SharePartition > sharePartitions = new LinkedHashMap <>();
1370
+ sharePartitions .put (tp0 , sp0 );
1371
+
1372
+ ShareFetch shareFetch = new ShareFetch (FETCH_PARAMS , "grp" , Uuid .randomUuid ().toString (),
1373
+ new CompletableFuture <>(), List .of (tp0 ), BATCH_SIZE , MAX_FETCH_RECORDS ,
1374
+ BROKER_TOPIC_STATS );
1375
+
1376
+ when (sp0 .nextFetchOffset ()).thenReturn (10L );
1377
+
1378
+ // Fetch offset does not match with the cached entry for sp0, hence, a replica manager fetch will happen for sp0.
1379
+ when (sp0 .fetchOffsetMetadata (anyLong ())).thenReturn (Optional .empty ());
1380
+
1381
+ // Mocking remote storage read result for tp0.
1382
+ doAnswer (invocation -> buildLocalAndRemoteFetchResult (Set .of (), Set .of (tp0 ))).when (replicaManager ).readFromLog (any (), any (), any (ReplicaQuota .class ), anyBoolean ());
1383
+
1384
+ // Remote fetch related mocks. Remote fetch object does not complete within tryComplete in this mock.
1385
+ RemoteLogManager remoteLogManager = mock (RemoteLogManager .class );
1386
+ when (remoteLogManager .asyncRead (any (), any ())).thenReturn (mock (Future .class ));
1387
+ when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1388
+
1389
+ Partition p0 = mock (Partition .class );
1390
+ when (p0 .isLeader ()).thenReturn (false );
1391
+
1392
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1393
+
1394
+ Uuid fetchId = Uuid .randomUuid ();
1395
+ DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1396
+ .withShareFetchData (shareFetch )
1397
+ .withSharePartitions (sharePartitions )
1398
+ .withReplicaManager (replicaManager )
1399
+ .withPartitionMaxBytesStrategy (mockPartitionMaxBytes (Set .of (tp0 )))
1400
+ .withFetchId (fetchId )
1401
+ .build ());
1402
+
1403
+ // All the topic partitions are acquirable.
1404
+ when (sp0 .maybeAcquireFetchLock (fetchId )).thenReturn (true );
1405
+
1406
+ // Mock the behaviour of replica manager such that remote storage fetch completion timer task completes on adding it to the watch queue.
1407
+ doAnswer (invocationOnMock -> {
1408
+ TimerTask timerTask = invocationOnMock .getArgument (0 );
1409
+ timerTask .run ();
1410
+ return null ;
1411
+ }).when (replicaManager ).addShareFetchTimerRequest (any ());
1412
+
1413
+ assertFalse (delayedShareFetch .isCompleted ());
1414
+ assertTrue (delayedShareFetch .tryComplete ());
1415
+ assertTrue (delayedShareFetch .isCompleted ());
1416
+ // Remote fetch object gets created for delayed share fetch object.
1417
+ assertNotNull (delayedShareFetch .pendingRemoteFetches ());
1418
+ // Verify the locks are released for local log read topic partitions tp0.
1419
+ Mockito .verify (delayedShareFetch , times (1 )).releasePartitionLocks (Set .of (tp0 ));
1420
+ assertTrue (delayedShareFetch .lock ().tryLock ());
1421
+ delayedShareFetch .lock ().unlock ();
1422
+ }
1423
+
1291
1424
@ Test
1292
1425
public void testRemoteStorageFetchTryCompleteThrowsException () {
1293
1426
ReplicaManager replicaManager = mock (ReplicaManager .class );
@@ -1516,6 +1649,16 @@ public void testRemoteStorageFetchRequestCompletionOnFutureCompletionFailure() {
1516
1649
when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1517
1650
1518
1651
Uuid fetchId = Uuid .randomUuid ();
1652
+
1653
+ Partition p0 = mock (Partition .class );
1654
+ when (p0 .isLeader ()).thenReturn (true );
1655
+
1656
+ Partition p1 = mock (Partition .class );
1657
+ when (p1 .isLeader ()).thenReturn (true );
1658
+
1659
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1660
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
1661
+
1519
1662
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1520
1663
.withShareFetchData (shareFetch )
1521
1664
.withSharePartitions (sharePartitions )
@@ -1586,6 +1729,12 @@ public void testRemoteStorageFetchRequestCompletionOnFutureCompletionSuccessfull
1586
1729
when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1587
1730
1588
1731
Uuid fetchId = Uuid .randomUuid ();
1732
+
1733
+ Partition p0 = mock (Partition .class );
1734
+ when (p0 .isLeader ()).thenReturn (true );
1735
+
1736
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1737
+
1589
1738
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1590
1739
.withShareFetchData (shareFetch )
1591
1740
.withSharePartitions (sharePartitions )
@@ -1679,6 +1828,19 @@ public void testRemoteStorageFetchRequestCompletionAlongWithLocalLogRead() {
1679
1828
}).when (remoteLogManager ).asyncRead (any (), any ());
1680
1829
when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1681
1830
1831
+ Partition p0 = mock (Partition .class );
1832
+ when (p0 .isLeader ()).thenReturn (true );
1833
+
1834
+ Partition p1 = mock (Partition .class );
1835
+ when (p1 .isLeader ()).thenReturn (true );
1836
+
1837
+ Partition p2 = mock (Partition .class );
1838
+ when (p2 .isLeader ()).thenReturn (true );
1839
+
1840
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1841
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
1842
+ when (replicaManager .getPartitionOrException (tp2 .topicPartition ())).thenReturn (p2 );
1843
+
1682
1844
Uuid fetchId = Uuid .randomUuid ();
1683
1845
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1684
1846
.withShareFetchData (shareFetch )
@@ -1761,6 +1923,16 @@ public void testRemoteStorageFetchHappensForAllTopicPartitions() {
1761
1923
when (replicaManager .remoteLogManager ()).thenReturn (Option .apply (remoteLogManager ));
1762
1924
1763
1925
Uuid fetchId = Uuid .randomUuid ();
1926
+
1927
+ Partition p0 = mock (Partition .class );
1928
+ when (p0 .isLeader ()).thenReturn (true );
1929
+
1930
+ Partition p1 = mock (Partition .class );
1931
+ when (p1 .isLeader ()).thenReturn (true );
1932
+
1933
+ when (replicaManager .getPartitionOrException (tp0 .topicPartition ())).thenReturn (p0 );
1934
+ when (replicaManager .getPartitionOrException (tp1 .topicPartition ())).thenReturn (p1 );
1935
+
1764
1936
DelayedShareFetch delayedShareFetch = spy (DelayedShareFetchBuilder .builder ()
1765
1937
.withShareFetchData (shareFetch )
1766
1938
.withSharePartitions (sharePartitions )
0 commit comments