X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FSimpleShardDataTreeCohortTest.java;h=7a4cb9b5efecc3233826c92f6ac7331bce478e4a;hb=9905bf0575ff196a531eb114e89b1bdb7226bc6c;hp=657d7b3e83f8a14332f0210809dfc83c63385bee;hpb=4d1709660b7af992d4c382a2a38debb5c7d64fb9;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/SimpleShardDataTreeCohortTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/SimpleShardDataTreeCohortTest.java index 657d7b3e83..7a4cb9b5ef 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/SimpleShardDataTreeCohortTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/SimpleShardDataTreeCohortTest.java @@ -7,29 +7,30 @@ */ package org.opendaylight.controller.cluster.datastore; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import com.google.common.util.concurrent.ListenableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import com.google.common.primitives.UnsignedLong; +import com.google.common.util.concurrent.FutureCallback; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; -import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree; /** * Unit tests for SimpleShardDataTreeCohort. @@ -37,106 +38,210 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree * @author Thomas Pantelis */ public class SimpleShardDataTreeCohortTest extends AbstractTest { - @Mock - private TipProducingDataTree mockDataTree; - @Mock private ShardDataTree mockShardDataTree; @Mock private DataTreeModification mockModification; + @Mock + private CompositeDataTreeCohort mockUserCohorts; + + @Mock + private FutureCallback mockPreCallback; + private SimpleShardDataTreeCohort cohort; @Before public void setup() { MockitoAnnotations.initMocks(this); - doReturn(mockDataTree).when(mockShardDataTree).getDataTree(); + doReturn(Optional.empty()).when(mockUserCohorts).commit(); + doReturn(Optional.empty()).when(mockUserCohorts).abort(); - cohort = new SimpleShardDataTreeCohort(mockShardDataTree, mockModification, nextTransactionId()); + cohort = new SimpleShardDataTreeCohort(mockShardDataTree, mockModification, nextTransactionId(), + mockUserCohorts, Optional.empty()); } @Test - public void testCanCommitSuccess() throws Exception { - ListenableFuture future = cohort.canCommit(); - assertNotNull("Future is null", future); - assertEquals("Future", true, future.get(3, TimeUnit.SECONDS)); - verify(mockDataTree).validate(mockModification); + public void testCanCommitSuccess() { + canCommitSuccess(); } - @Test(expected=OptimisticLockFailedException.class) - public void testCanCommitWithConflictingModEx() throws Throwable { - doThrow(new ConflictingModificationAppliedException(YangInstanceIdentifier.EMPTY, "mock")). - when(mockDataTree).validate(mockModification); - try { - cohort.canCommit().get(); - } catch (ExecutionException e) { - throw e.getCause(); - } + private void canCommitSuccess() { + doAnswer(invocation -> { + invocation.getArgument(0).successfulCanCommit(); + return null; + }).when(mockShardDataTree).startCanCommit(cohort); + + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.canCommit(callback); + + verify(callback).onSuccess(null); + verifyNoMoreInteractions(callback); + } + + private void testValidatationPropagates(final Exception cause) { + doAnswer(invocation -> { + invocation.getArgument(0).failedCanCommit(cause); + return null; + }).when(mockShardDataTree).startCanCommit(cohort); + + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.canCommit(callback); + + verify(callback).onFailure(cause); + verifyNoMoreInteractions(callback); } - @Test(expected=TransactionCommitFailedException.class) - public void testCanCommitWithDataValidationEx() throws Throwable { - doThrow(new DataValidationFailedException(YangInstanceIdentifier.EMPTY, "mock")). - when(mockDataTree).validate(mockModification); - try { - cohort.canCommit().get(); - } catch (ExecutionException e) { - throw e.getCause(); - } + @Test + public void testCanCommitWithConflictingModEx() { + testValidatationPropagates(new ConflictingModificationAppliedException(YangInstanceIdentifier.EMPTY, "mock")); } - @Test(expected=IllegalArgumentException.class) - public void testCanCommitWithIllegalArgumentEx() throws Throwable { - doThrow(new IllegalArgumentException("mock")).when(mockDataTree).validate(mockModification); - try { - cohort.canCommit().get(); - } catch (ExecutionException e) { - throw e.getCause(); - } + @Test + public void testCanCommitWithDataValidationEx() { + testValidatationPropagates(new DataValidationFailedException(YangInstanceIdentifier.EMPTY, "mock")); } @Test - public void testPreCommitAndCommitSuccess() throws Exception { - DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class); - doReturn(mockCandidate ).when(mockDataTree).prepare(mockModification); + public void testCanCommitWithIllegalArgumentEx() { + testValidatationPropagates(new IllegalArgumentException("mock")); + } + + private DataTreeCandidateTip preCommitSuccess() { + final DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class); + doAnswer(invocation -> { + invocation.getArgument(0).successfulPreCommit(mockCandidate); + return null; + }).when(mockShardDataTree).startPreCommit(cohort); - ListenableFuture future = cohort.preCommit(); - assertNotNull("Future is null", future); - future.get(); - verify(mockDataTree).prepare(mockModification); + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.preCommit(callback); + + verify(callback).onSuccess(mockCandidate); + verifyNoMoreInteractions(callback); assertSame("getCandidate", mockCandidate, cohort.getCandidate()); - future = cohort.commit(); - assertNotNull("Future is null", future); - future.get(); - verify(mockDataTree).commit(mockCandidate); + return mockCandidate; } - @Test(expected=IllegalArgumentException.class) - public void testPreCommitWithIllegalArgumentEx() throws Throwable { - doThrow(new IllegalArgumentException("mock")).when(mockDataTree).prepare(mockModification); - try { - cohort.preCommit().get(); - } catch (ExecutionException e) { - throw e.getCause(); - } + @Test + public void testPreCommitAndCommitSuccess() { + canCommitSuccess(); + final DataTreeCandidateTip candidate = preCommitSuccess(); + + doAnswer(invocation -> { + invocation.getArgument(0).successfulCommit(UnsignedLong.valueOf(0), () -> { }); + return null; + }).when(mockShardDataTree).startCommit(cohort, candidate); + + @SuppressWarnings("unchecked") + final FutureCallback mockCommitCallback = mock(FutureCallback.class); + cohort.commit(mockCommitCallback); + + verify(mockCommitCallback).onSuccess(any(UnsignedLong.class)); + verifyNoMoreInteractions(mockCommitCallback); + + verify(mockUserCohorts).commit(); } - @Test(expected=IllegalArgumentException.class) - public void testCommitWithIllegalArgumentEx() throws Throwable { - doThrow(new IllegalArgumentException("mock")).when(mockDataTree).commit(any(DataTreeCandidateTip.class)); - try { - cohort.commit().get(); - } catch (ExecutionException e) { - throw e.getCause(); - } + @Test + public void testPreCommitWithIllegalArgumentEx() { + canCommitSuccess(); + + final Exception cause = new IllegalArgumentException("mock"); + doAnswer(invocation -> { + invocation.getArgument(0).failedPreCommit(cause); + return null; + }).when(mockShardDataTree).startPreCommit(cohort); + + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.preCommit(callback); + + verify(callback).onFailure(cause); + verifyNoMoreInteractions(callback); + + verify(mockUserCohorts).abort(); + } + + @Test + public void testPreCommitWithReportedFailure() { + canCommitSuccess(); + + final Exception cause = new IllegalArgumentException("mock"); + cohort.reportFailure(cause); + + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.preCommit(callback); + + verify(callback).onFailure(cause); + verifyNoMoreInteractions(callback); + + verify(mockShardDataTree, never()).startPreCommit(cohort); + } + + @Test + public void testCommitWithIllegalArgumentEx() { + canCommitSuccess(); + final DataTreeCandidateTip candidate = preCommitSuccess(); + + final Exception cause = new IllegalArgumentException("mock"); + doAnswer(invocation -> { + invocation.getArgument(0).failedCommit(cause); + return null; + }).when(mockShardDataTree).startCommit(cohort, candidate); + + @SuppressWarnings("unchecked") + final FutureCallback callback = mock(FutureCallback.class); + cohort.commit(callback); + + verify(callback).onFailure(cause); + verifyNoMoreInteractions(callback); + + verify(mockUserCohorts).abort(); + } + + private static Future abort(final ShardDataTreeCohort cohort) { + final CompletableFuture f = new CompletableFuture<>(); + cohort.abort(new FutureCallback() { + @Override + public void onSuccess(final Void result) { + f.complete(null); + } + + @Override + public void onFailure(final Throwable failure) { + f.completeExceptionally(failure); + } + }); + + return f; } @Test public void testAbort() throws Exception { - cohort.abort().get(); + doReturn(Boolean.TRUE).when(mockShardDataTree).startAbort(cohort); + + abort(cohort).get(); + verify(mockShardDataTree).startAbort(cohort); + } + + @Test + public void testAbortWithCohorts() throws Exception { + doReturn(true).when(mockShardDataTree).startAbort(cohort); + + doReturn(Optional.of(CompletableFuture.completedFuture(null))).when(mockUserCohorts).abort(); + + final Future abortFuture = abort(cohort); + + abortFuture.get(); + verify(mockShardDataTree).startAbort(cohort); } }