2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.dom.store.inmemory;
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertSame;
16 import static org.junit.Assert.assertThrows;
17 import static org.mockito.ArgumentMatchers.any;
18 import static org.mockito.Mockito.doNothing;
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.doThrow;
21 import static org.mockito.Mockito.verify;
23 import java.util.concurrent.ExecutionException;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.mockito.Mock;
27 import org.mockito.junit.MockitoJUnitRunner;
28 import org.opendaylight.mdsal.common.api.OptimisticLockFailedException;
29 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
30 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
31 import org.opendaylight.mdsal.dom.spi.store.SnapshotBackedTransactions;
32 import org.opendaylight.mdsal.dom.spi.store.SnapshotBackedWriteTransaction.TransactionReadyPrototype;
33 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
34 import org.opendaylight.yangtools.yang.common.ErrorTag;
35 import org.opendaylight.yangtools.yang.common.ErrorType;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.tree.api.ConflictingModificationAppliedException;
38 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
39 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
40 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeSnapshot;
41 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
43 @RunWith(MockitoJUnitRunner.StrictStubs.class)
44 public class InMemoryDOMStoreThreePhaseCommitCohortTest {
46 private InMemoryDOMDataStore dataStore;
48 private DataTreeCandidate candidate;
50 private TransactionReadyPrototype<String> prototype;
52 private DataTreeSnapshot snapshot;
54 private DataTreeModification modification;
57 public void canCommitTest() throws Exception {
58 doNothing().when(dataStore).validate(any());
59 prepareSimpleCohort().canCommit();
60 verify(dataStore).validate(any());
64 public void canCommitWithOperationError() throws Exception {
65 doReturn(modification).when(snapshot).newModification();
66 final var operationError = new RuntimeException();
67 final var cohort = new InMemoryDOMStoreThreePhaseCommitCohort(dataStore,
68 SnapshotBackedTransactions.newWriteTransaction("test", false, snapshot, prototype), modification,
71 assertSame(operationError, assertFailsCanCommit(cohort));
75 public void canCommitTestWithOptimisticLockFailedException() throws Exception {
76 final var cause = new ConflictingModificationAppliedException(YangInstanceIdentifier.empty(), "testException");
77 doThrow(cause).when(dataStore).validate(any());
79 final var ex = assertFailsCanCommit(prepareSimpleCohort());
80 assertThat(ex, instanceOf(OptimisticLockFailedException.class));
81 assertSame(cause, ex.getCause());
82 final var errors = ((OptimisticLockFailedException) ex).getErrorList();
83 assertEquals(1, errors.size());
84 final var error = errors.get(0);
85 assertEquals(ErrorSeverity.ERROR, error.getSeverity());
86 assertEquals(ErrorType.APPLICATION, error.getErrorType());
87 assertEquals(ErrorTag.RESOURCE_DENIED, error.getTag());
91 public void canCommitTestWithTransactionCommitFailedException() throws Exception {
92 final var cause = new DataValidationFailedException(YangInstanceIdentifier.empty(), "testException");
93 doThrow(cause).when(dataStore).validate(any());
95 final var ex = assertFailsCanCommit(prepareSimpleCohort());
96 assertThat(ex, instanceOf(TransactionCommitFailedException.class));
97 assertSame(cause, ex.getCause());
98 final var errors = ((TransactionCommitFailedException) ex).getErrorList();
99 assertEquals(1, errors.size());
100 final var error = errors.get(0);
101 assertEquals(ErrorSeverity.ERROR, error.getSeverity());
102 assertEquals(ErrorType.APPLICATION, error.getErrorType());
103 assertEquals(ErrorTag.OPERATION_FAILED, error.getTag());
107 public void canCommitTestWithUnknownException() throws Exception {
108 final var cause = new UnsupportedOperationException("testException");
109 doThrow(cause).when(dataStore).validate(any());
111 assertSame(cause, assertFailsCanCommit(prepareSimpleCohort()));
115 public void preCommitTest() throws Exception {
116 doReturn(candidate).when(dataStore).prepare(any());
117 prepareSimpleCohort().preCommit().get();
118 verify(dataStore).prepare(any());
122 public void preCommitTestWithUnknownException() throws Exception {
123 final var cause = new UnsupportedOperationException("testException");
124 doThrow(cause).when(dataStore).prepare(any());
126 final var future = prepareSimpleCohort().preCommit();
127 final var ex = assertThrows(ExecutionException.class, future::get).getCause();
128 assertSame(cause, ex);
132 public void abortTest() throws Exception {
133 doReturn(candidate).when(dataStore).prepare(any());
135 final var cohort = prepareSimpleCohort();
137 assertNotNull(cohort.candidate);
140 assertNull(cohort.candidate);
144 public void commitTest() throws Exception {
145 doNothing().when(dataStore).commit(any());
146 doReturn(candidate).when(dataStore).prepare(any());
148 final var cohort = prepareSimpleCohort();
151 verify(dataStore).commit(any());
154 private InMemoryDOMStoreThreePhaseCommitCohort prepareSimpleCohort() {
155 doReturn(modification).when(snapshot).newModification();
156 return new InMemoryDOMStoreThreePhaseCommitCohort(dataStore,
157 SnapshotBackedTransactions.newWriteTransaction("test", false, snapshot, prototype),
161 private static Throwable assertFailsCanCommit(final DOMStoreThreePhaseCommitCohort cohort) {
162 final var future = cohort.canCommit();
163 return assertThrows(ExecutionException.class, future::get).getCause();