use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method existingCreationIncomingCreationYieldsError.
/**
* When there is an existing creation for a model, and a new creation for that
* model comes in, an error should be returned. In other words, it is illegal to
* create a mutation twice.
* @throws DataStoreException On failure to query storage to assert post-action value of mutation
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
*/
@Test
public void existingCreationIncomingCreationYieldsError() throws DataStoreException, InterruptedException {
// Arrange an existing creation mutation
BlogOwner modelInExistingMutation = BlogOwner.builder().name("The Real Papa Tony").build();
PendingMutation<BlogOwner> existingCreation = PendingMutation.creation(modelInExistingMutation, schema);
String existingCreationId = existingCreation.getMutationId().toString();
mutationOutbox.enqueue(existingCreation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Act: try to create the blog owner again -- but there's already a pending creation
BlogOwner modelInIncomingMutation = modelInExistingMutation.copyOfBuilder().name("Someone Posing as Papa Tony Who isn't \uD83D\uDCAF legit.").build();
PendingMutation<BlogOwner> incomingCreation = PendingMutation.creation(modelInIncomingMutation, schema);
String incomingCreationId = incomingCreation.getMutationId().toString();
TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(incomingCreation).test();
// Assert: caused a failure.
enqueueObserver.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
enqueueObserver.assertError(throwable -> throwable instanceof DataStoreException);
// Assert: original mutation is present, but the new one isn't.
PendingMutation.PersistentRecord storedMutation = storage.query(PersistentRecord.class, Where.id(existingCreationId)).get(0);
assertEquals(modelInExistingMutation, converter.fromRecord(storedMutation).getMutatedItem());
assertTrue(storage.query(PersistentRecord.class, Where.id(incomingCreationId)).isEmpty());
// Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox)
assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getId()));
assertEquals(existingCreation, mutationOutbox.peek());
}
use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method enqueueIsSynchronized.
/**
* When two creations for the same model are enqueued, the second should fail. This is similar to
* {@link #existingCreationIncomingCreationYieldsError}, except that the Completable's from the two enqueue calls
* are concatenated into the same stream. The second enqueue should not check if an item exists in the queue
* until the first enqueue is completed.
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
*/
@Test
public void enqueueIsSynchronized() throws InterruptedException {
// Arrange an existing creation mutation
BlogOwner modelInExistingMutation = BlogOwner.builder().name("The Real Papa Tony").build();
PendingMutation<BlogOwner> firstCreation = PendingMutation.creation(modelInExistingMutation, schema);
PendingMutation<BlogOwner> secondCreation = PendingMutation.creation(modelInExistingMutation, schema);
TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(firstCreation).andThen(mutationOutbox.enqueue(secondCreation)).test();
// Assert: caused a failure.
enqueueObserver.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
enqueueObserver.assertError(throwable -> throwable instanceof DataStoreException);
}
use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method existingUpdateIncomingCreationYieldsError.
/**
* When there is an existing update for a model, and a new creation for that
* model comes in, an error should be returned. In other words, you can't create
* something that already exists and is being updated.
* @throws DataStoreException On failure to to query which mutations are in storage
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
*/
@Test
public void existingUpdateIncomingCreationYieldsError() throws DataStoreException, InterruptedException {
// Arrange an existing update mutation
BlogOwner modelInExistingMutation = BlogOwner.builder().name("Tony with improvements applied").build();
PendingMutation<BlogOwner> existingUpdate = PendingMutation.update(modelInExistingMutation, schema);
String exitingUpdateId = existingUpdate.getMutationId().toString();
mutationOutbox.enqueue(existingUpdate).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Act: try to CREATE tony again -- but isn't he already created, if there's an update?
BlogOwner modelInIncomingMutation = modelInExistingMutation.copyOfBuilder().name("Brand new tony").build();
PendingMutation<BlogOwner> incomingCreation = PendingMutation.creation(modelInIncomingMutation, schema);
String incomingCreationId = incomingCreation.getMutationId().toString();
TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(incomingCreation).test();
// Assert: caused a failure.
enqueueObserver.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
enqueueObserver.assertError(throwable -> throwable instanceof DataStoreException);
// Assert: original mutation is present, but the new one isn't.
PendingMutation.PersistentRecord storedMutation = storage.query(PersistentRecord.class, Where.id(exitingUpdateId)).get(0);
assertEquals(modelInExistingMutation, converter.fromRecord(storedMutation).getMutatedItem());
assertTrue(storage.query(PersistentRecord.class, Where.id(incomingCreationId)).isEmpty());
// Existing mutation still attainable as next mutation (right now, its the ONLY mutation in outbox)
assertTrue(mutationOutbox.hasPendingMutation(modelInExistingMutation.getId()));
assertEquals(existingUpdate, mutationOutbox.peek());
}
use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.
the class SubscriptionProcessorTest method appSyncInvokedWhenSubscriptionsStarted.
/**
* When {@link SubscriptionProcessor#startSubscriptions()} is invoked,
* the {@link AppSync} client receives subscription requests.
*/
@Test
public void appSyncInvokedWhenSubscriptionsStarted() {
// For every Class-SubscriptionType pairing, use a CountDownLatch
// to tell whether or not we've "seen" a subscription event for it.
Map<Pair<ModelSchema, SubscriptionType>, CountDownLatch> seen = new HashMap<>();
// Build a stream of such pairs.
Observable.fromIterable(modelSchemas).flatMap(modelSchema -> Observable.fromArray(SubscriptionType.values()).map(value -> Pair.create(modelSchema, value))).blockingForEach(pair -> {
// For each one, store a latch. Add a mocking behavior to count down
// the latch when the subscription API is hit, for that class and subscription type.
CountDownLatch latch = new CountDownLatch(1);
seen.put(Pair.create(pair.first, pair.second), latch);
Answer<Cancelable> answer = invocation -> {
latch.countDown();
return new NoOpCancelable();
};
arrangeSubscription(appSync, answer, pair.first, pair.second);
});
// Act: start some subscriptions.
try {
subscriptionProcessor.startSubscriptions();
} catch (DataStoreException exception) {
// startSubscriptions throws this exception if it doesn't receive the start_ack messages after a time out.
// This test doesn't mock those start_ack messages, so this expection is expected. That's okay though -
// we just want to verify that the subscriptions were requested.
}
// Make sure that all of the subscriptions have been
Observable.fromIterable(seen.entrySet()).blockingForEach(entry -> {
CountDownLatch latch = entry.getValue();
assertTrue(latch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
});
}
use of com.amplifyframework.datastore.DataStoreException in project amplify-android by aws-amplify.
the class SyncProcessorTest method retriedOnAppSyncFailure.
/**
* Verify that retry is called on appsync failure when syncRetry is set to true.
*
* @throws AmplifyException On failure to build GraphQLRequest for sync query.
*/
@Test
public void retriedOnAppSyncFailure() throws AmplifyException {
// Arrange: mock failure when invoking hydrate on the mock object.
requestRetry = mock(RetryHandler.class);
when(requestRetry.retry(any(), any())).thenReturn(Single.error(new DataStoreException("PaginatedResult<ModelWithMetadata<BlogOwner>>", "")));
initSyncProcessor(10_000);
AppSyncMocking.sync(appSync).mockFailure(new DataStoreException("Something timed out during sync.", ""));
// Act: call hydrate.
syncProcessor.hydrate().test(false).assertNotComplete();
verify(requestRetry, times(1)).retry(any(), any());
}
Aggregations