|
20 | 20 |
|
21 | 21 | import static org.testng.Assert.assertEquals; |
22 | 22 |
|
| 23 | +import java.util.UUID; |
| 24 | +import java.util.concurrent.TimeUnit; |
23 | 25 | import org.apache.bookkeeper.mledger.ManagedCursor; |
24 | 26 | import org.apache.bookkeeper.mledger.ManagedLedgerConfig; |
25 | 27 | import org.apache.bookkeeper.mledger.ManagedLedgerInfo; |
26 | 28 | import org.apache.bookkeeper.mledger.ManagedLedgerInfo.CursorInfo; |
27 | 29 | import org.apache.bookkeeper.mledger.ManagedLedgerInfo.MessageRangeInfo; |
28 | 30 | import org.apache.bookkeeper.test.MockedBookKeeperTestCase; |
| 31 | +import org.awaitility.Awaitility; |
| 32 | +import org.testng.Assert; |
29 | 33 | import org.testng.annotations.Test; |
30 | 34 |
|
31 | 35 | public class ManagedLedgerFactoryTest extends MockedBookKeeperTestCase { |
@@ -71,4 +75,43 @@ public void testGetManagedLedgerInfoWithClose() throws Exception { |
71 | 75 | assertEquals(mri.to.entryId, 0); |
72 | 76 | } |
73 | 77 |
|
| 78 | + /** |
| 79 | + * see: https://github.com/apache/pulsar/pull/18688 |
| 80 | + */ |
| 81 | + @Test |
| 82 | + public void testConcurrentCloseLedgerAndSwitchLedgerForReproduceIssue() throws Exception { |
| 83 | + String managedLedgerName = "lg_" + UUID.randomUUID().toString().replaceAll("-", "_"); |
| 84 | + |
| 85 | + ManagedLedgerConfig config = new ManagedLedgerConfig(); |
| 86 | + config.setThrottleMarkDelete(1); |
| 87 | + config.setMaximumRolloverTime(Integer.MAX_VALUE, TimeUnit.SECONDS); |
| 88 | + config.setMaxEntriesPerLedger(5); |
| 89 | + |
| 90 | + // create managedLedger once and close it. |
| 91 | + ManagedLedgerImpl managedLedger1 = (ManagedLedgerImpl) factory.open(managedLedgerName, config); |
| 92 | + waitManagedLedgerStateEquals(managedLedger1, ManagedLedgerImpl.State.LedgerOpened); |
| 93 | + managedLedger1.close(); |
| 94 | + |
| 95 | + // create managedLedger the second time. |
| 96 | + ManagedLedgerImpl managedLedger2 = (ManagedLedgerImpl) factory.open(managedLedgerName, config); |
| 97 | + waitManagedLedgerStateEquals(managedLedger2, ManagedLedgerImpl.State.LedgerOpened); |
| 98 | + |
| 99 | + // Mock the task create ledger complete now, it will change the state to another value which not is Closed. |
| 100 | + // Close managedLedger1 the second time. |
| 101 | + managedLedger1.createComplete(1, null, null); |
| 102 | + managedLedger1.close(); |
| 103 | + |
| 104 | + // Verify managedLedger2 is still there. |
| 105 | + Assert.assertFalse(factory.ledgers.isEmpty()); |
| 106 | + Assert.assertEquals(factory.ledgers.get(managedLedger2.getName()).join(), managedLedger2); |
| 107 | + |
| 108 | + // cleanup. |
| 109 | + managedLedger2.close(); |
| 110 | + } |
| 111 | + |
| 112 | + private void waitManagedLedgerStateEquals(ManagedLedgerImpl managedLedger, ManagedLedgerImpl.State expectedStat){ |
| 113 | + Awaitility.await().untilAsserted(() -> |
| 114 | + Assert.assertTrue(managedLedger.getState() == expectedStat)); |
| 115 | + } |
| 116 | + |
74 | 117 | } |
0 commit comments