|
17 | 17 | */ |
18 | 18 | package org.apache.beam.sdk.io.gcp.spanner.changestreams.action; |
19 | 19 |
|
| 20 | +import static org.apache.beam.sdk.io.gcp.spanner.changestreams.ChangeStreamsConstants.MAX_INCLUSIVE_END_AT; |
20 | 21 | import static org.apache.beam.sdk.io.gcp.spanner.changestreams.model.PartitionMetadata.State.SCHEDULED; |
21 | 22 | import static org.junit.Assert.assertEquals; |
| 23 | +import static org.junit.Assert.assertNotEquals; |
22 | 24 | import static org.mockito.ArgumentMatchers.any; |
23 | 25 | import static org.mockito.ArgumentMatchers.eq; |
24 | 26 | import static org.mockito.Mockito.mock; |
|
55 | 57 | import org.joda.time.Instant; |
56 | 58 | import org.junit.Before; |
57 | 59 | import org.junit.Test; |
| 60 | +import org.mockito.ArgumentCaptor; |
58 | 61 |
|
59 | 62 | public class QueryChangeStreamActionTest { |
60 | 63 | private static final String PARTITION_TOKEN = "partitionToken"; |
@@ -613,6 +616,53 @@ public void testQueryChangeStreamWithStreamFinished() { |
613 | 616 | assertEquals(ProcessContinuation.stop(), result); |
614 | 617 | verify(partitionMetadataDao).updateWatermark(PARTITION_TOKEN, WATERMARK_TIMESTAMP); |
615 | 618 | verify(partitionMetadataDao).updateToFinished(PARTITION_TOKEN); |
| 619 | + verify(metrics).decActivePartitionReadCounter(); |
| 620 | + |
| 621 | + verify(dataChangeRecordAction, never()).run(any(), any(), any(), any(), any(), any()); |
| 622 | + verify(heartbeatRecordAction, never()).run(any(), any(), any(), any(), any()); |
| 623 | + verify(childPartitionsRecordAction, never()).run(any(), any(), any(), any(), any()); |
| 624 | + verify(partitionStartRecordAction, never()).run(any(), any(), any(), any(), any()); |
| 625 | + verify(partitionEndRecordAction, never()).run(any(), any(), any(), any(), any()); |
| 626 | + verify(partitionEventRecordAction, never()).run(any(), any(), any(), any(), any()); |
| 627 | + } |
| 628 | + |
| 629 | + @Test |
| 630 | + public void testQueryChangeStreamFinishedWithResume() { |
| 631 | + partition = |
| 632 | + PartitionMetadata.newBuilder() |
| 633 | + .setPartitionToken(PARTITION_TOKEN) |
| 634 | + .setParentTokens(Sets.newHashSet("parentToken")) |
| 635 | + .setStartTimestamp(PARTITION_START_TIMESTAMP) |
| 636 | + .setEndTimestamp(MAX_INCLUSIVE_END_AT) |
| 637 | + .setHeartbeatMillis(PARTITION_HEARTBEAT_MILLIS) |
| 638 | + .setState(SCHEDULED) |
| 639 | + .setWatermark(WATERMARK_TIMESTAMP) |
| 640 | + .setScheduledAt(Timestamp.now()) |
| 641 | + .build(); |
| 642 | + when(partitionMetadataMapper.from(any())).thenReturn(partition); |
| 643 | + |
| 644 | + final ChangeStreamResultSet changeStreamResultSet = mock(ChangeStreamResultSet.class); |
| 645 | + final ArgumentCaptor<Timestamp> timestampCaptor = ArgumentCaptor.forClass(Timestamp.class); |
| 646 | + when(changeStreamDao.changeStreamQuery( |
| 647 | + eq(PARTITION_TOKEN), |
| 648 | + eq(PARTITION_START_TIMESTAMP), |
| 649 | + timestampCaptor.capture(), |
| 650 | + eq(PARTITION_HEARTBEAT_MILLIS))) |
| 651 | + .thenReturn(changeStreamResultSet); |
| 652 | + when(changeStreamResultSet.next()).thenReturn(false); |
| 653 | + when(watermarkEstimator.currentWatermark()).thenReturn(WATERMARK); |
| 654 | + when(restrictionTracker.tryClaim(any(Timestamp.class))).thenReturn(true); |
| 655 | + |
| 656 | + final ProcessContinuation result = |
| 657 | + action.run( |
| 658 | + partition, restrictionTracker, outputReceiver, watermarkEstimator, bundleFinalizer); |
| 659 | + assertEquals(ProcessContinuation.resume(), result); |
| 660 | + assertNotEquals(MAX_INCLUSIVE_END_AT, timestampCaptor.getValue()); |
| 661 | + |
| 662 | + verify(restrictionTracker).tryClaim(timestampCaptor.getValue()); |
| 663 | + verify(partitionMetadataDao).updateWatermark(PARTITION_TOKEN, WATERMARK_TIMESTAMP); |
| 664 | + verify(partitionMetadataDao, never()).updateToFinished(PARTITION_TOKEN); |
| 665 | + verify(metrics, never()).decActivePartitionReadCounter(); |
616 | 666 |
|
617 | 667 | verify(dataChangeRecordAction, never()).run(any(), any(), any(), any(), any(), any()); |
618 | 668 | verify(heartbeatRecordAction, never()).run(any(), any(), any(), any(), any()); |
|
0 commit comments