Skip to content

Commit 501695d

Browse files
committed
One of our new DDB integration tests is failing on GitHub. This change attempts to fix that by 1) including a sleep between writing events to ensure that they have different timestamps; and 2) waiting for the GSI to reach eventual consistency.
Signed-off-by: David Venable <dlv@amazon.com>
1 parent ce57396 commit 501695d

1 file changed

Lines changed: 48 additions & 15 deletions

File tree

data-prepper-plugins/dynamodb-source-coordination-store/src/test/java/org/opensearch/dataprepper/plugins/sourcecoordinator/dynamodb/DynamoDbSourceCoordinationStoreIT.java

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,30 @@
2424
import org.opensearch.dataprepper.model.source.coordinator.SourcePartitionStatus;
2525
import org.opensearch.dataprepper.model.source.coordinator.SourcePartitionStoreItem;
2626
import org.opensearch.dataprepper.model.source.coordinator.exceptions.PartitionUpdateException;
27+
import software.amazon.awssdk.core.pagination.sync.SdkIterable;
2728
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
29+
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbIndex;
2830
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
2931
import software.amazon.awssdk.enhanced.dynamodb.Key;
3032
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
3133
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest;
34+
import software.amazon.awssdk.enhanced.dynamodb.model.Page;
35+
import software.amazon.awssdk.enhanced.dynamodb.model.QueryConditional;
36+
import software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest;
3237
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
3338

3439
import java.time.Duration;
3540
import java.time.Instant;
41+
import java.util.List;
3642
import java.util.Optional;
3743
import java.util.Random;
3844
import java.util.UUID;
45+
import java.util.concurrent.TimeUnit;
46+
import java.util.stream.Collectors;
47+
import java.util.stream.IntStream;
48+
import java.util.stream.Stream;
3949

50+
import static org.awaitility.Awaitility.await;
4051
import static org.hamcrest.MatcherAssert.assertThat;
4152
import static org.hamcrest.Matchers.equalTo;
4253
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
@@ -48,6 +59,8 @@
4859
import static org.hamcrest.Matchers.sameInstance;
4960
import static org.junit.jupiter.api.Assertions.assertThrows;
5061
import static org.mockito.Mockito.when;
62+
import static org.opensearch.dataprepper.plugins.sourcecoordinator.dynamodb.DynamoDbClientWrapper.SOURCE_STATUS_COMBINATION_KEY_GLOBAL_SECONDARY_INDEX;
63+
import static org.opensearch.dataprepper.plugins.sourcecoordinator.dynamodb.DynamoDbSourceCoordinationStore.SOURCE_STATUS_COMBINATION_KEY_FORMAT;
5164

5265
@ExtendWith(MockitoExtension.class)
5366
class DynamoDbSourceCoordinationStoreIT {
@@ -91,8 +104,8 @@ void setUp() {
91104
when(dynamoStoreSettings.getRegion()).thenReturn(region);
92105
when(dynamoStoreSettings.getStsRoleArn()).thenReturn(stsRoleArn);
93106
when(dynamoStoreSettings.getStsExternalId()).thenReturn(stsExternalId);
94-
when(dynamoStoreSettings.getProvisionedReadCapacityUnits()).thenReturn(1L);
95-
when(dynamoStoreSettings.getProvisionedWriteCapacityUnits()).thenReturn(1L);
107+
when(dynamoStoreSettings.getProvisionedReadCapacityUnits()).thenReturn(10L);
108+
when(dynamoStoreSettings.getProvisionedWriteCapacityUnits()).thenReturn(10L);
96109

97110
when(dynamoDbClientFactory.provideDynamoDbClient(region, stsRoleArn, stsExternalId)).thenReturn(dynamoDbClient);
98111

@@ -250,36 +263,56 @@ void tryCreatePartitionItem_creates_an_item() {
250263
}
251264

252265
@Test
253-
void tryAcquireAvailablePartition_gets_first_unassigned_partition() {
266+
void tryAcquireAvailablePartition_gets_first_unassigned_partition() throws InterruptedException {
254267
final DynamoDbSourceCoordinationStore objectUnderTest = createObjectUnderTest();
255268
final String partitionProgressState = UUID.randomUUID().toString();
256269

257-
final String unassignedPartitionKey1 = UUID.randomUUID().toString();
258-
final String unassignedPartitionKey2 = UUID.randomUUID().toString();
259-
final String unassignedPartitionKey3 = UUID.randomUUID().toString();
270+
final List<String> partitionKeys = IntStream.rangeClosed(1, 3)
271+
.mapToObj(i -> UUID.randomUUID() + "_" + i)
272+
.collect(Collectors.toList());
260273

261-
objectUnderTest.tryCreatePartitionItem(sourceIdentifier,
262-
unassignedPartitionKey1, SourcePartitionStatus.UNASSIGNED, 1L, partitionProgressState, false);
263-
objectUnderTest.tryCreatePartitionItem(sourceIdentifier,
264-
unassignedPartitionKey2, SourcePartitionStatus.UNASSIGNED, 1L, partitionProgressState, false);
265-
objectUnderTest.tryCreatePartitionItem(sourceIdentifier,
266-
unassignedPartitionKey3, SourcePartitionStatus.UNASSIGNED, 1L, partitionProgressState, false);
274+
for (final String partitionKey : partitionKeys) {
275+
final boolean createSuccess = objectUnderTest.tryCreatePartitionItem(sourceIdentifier,
276+
partitionKey, SourcePartitionStatus.UNASSIGNED, 1L, partitionProgressState, false);
277+
assertThat(createSuccess, equalTo(true));
278+
Thread.sleep(150);
279+
}
267280

268-
final Optional<SourcePartitionStoreItem> maybeAcquired =
269-
objectUnderTest.tryAcquireAvailablePartition(sourceIdentifier, ownerId, Duration.ofSeconds(20));
281+
await().atMost(10, TimeUnit.SECONDS).until(() -> {
282+
final String primaryKey = String.format(SOURCE_STATUS_COMBINATION_KEY_FORMAT, sourceIdentifier, SourcePartitionStatus.UNASSIGNED);
283+
final Stream<DynamoDbSourcePartitionItem> items = querySourceStatusIndex(primaryKey);
284+
285+
return items.count() == partitionKeys.size();
286+
});
287+
288+
final Optional<SourcePartitionStoreItem> maybeAcquired = objectUnderTest.tryAcquireAvailablePartition(sourceIdentifier, ownerId, Duration.ofSeconds(20));
270289

271290
assertThat(maybeAcquired, notNullValue());
272291
assertThat(maybeAcquired.isPresent(), equalTo(true));
273-
274292
final SourcePartitionStoreItem acquiredItem = maybeAcquired.get();
275293

276294
assertThat(acquiredItem, notNullValue());
295+
final String unassignedPartitionKey1 = partitionKeys.get(0);
296+
277297
assertThat(acquiredItem.getSourceIdentifier(), equalTo(sourceIdentifier));
278298
assertThat(acquiredItem.getSourcePartitionKey(), equalTo(unassignedPartitionKey1));
279299
assertThat(acquiredItem.getSourcePartitionStatus(), equalTo(SourcePartitionStatus.ASSIGNED));
280300
assertThat(acquiredItem.getPartitionOwner(), equalTo(ownerId));
281301
}
282302

303+
private Stream<DynamoDbSourcePartitionItem> querySourceStatusIndex(final String partitionKey) {
304+
final DynamoDbIndex<DynamoDbSourcePartitionItem> sourceStatusIndex = table.index(SOURCE_STATUS_COMBINATION_KEY_GLOBAL_SECONDARY_INDEX);
305+
final QueryEnhancedRequest queryEnhancedRequest = QueryEnhancedRequest.builder()
306+
.limit(1)
307+
.queryConditional(QueryConditional.keyEqualTo(Key.builder().partitionValue(partitionKey).build()))
308+
.build();
309+
310+
final SdkIterable<Page<DynamoDbSourcePartitionItem>> pages = sourceStatusIndex.query(queryEnhancedRequest);
311+
312+
return pages.stream()
313+
.flatMap(page -> page.items().stream());
314+
}
315+
283316
private DynamoDbSourcePartitionItem putDynamoDbSourcePartitionItem(final SourcePartitionStatus sourcePartitionStatus) {
284317
final DynamoDbSourcePartitionItem putItem = createUnsavedPartitionItem(sourcePartitionStatus);
285318
table.putItem(putItem);

0 commit comments

Comments
 (0)