2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.controller.cluster.datastore;
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertNull;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.same;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.verify;
16 import static org.mockito.Mockito.verifyNoMoreInteractions;
17 import static org.mockito.Mockito.when;
19 import akka.actor.ActorRef;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequestBuilder;
23 import org.opendaylight.controller.cluster.access.commands.ReadTransactionRequest;
24 import org.opendaylight.controller.cluster.access.commands.TransactionModification;
25 import org.opendaylight.controller.cluster.access.commands.TransactionRequest;
26 import org.opendaylight.controller.cluster.access.commands.TransactionSuccess;
27 import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
28 import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier;
29 import org.opendaylight.controller.cluster.access.concepts.FrontendType;
30 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
31 import org.opendaylight.controller.cluster.access.concepts.MemberName;
32 import org.opendaylight.controller.cluster.access.concepts.RequestEnvelope;
33 import org.opendaylight.controller.cluster.access.concepts.RequestException;
34 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
38 public class FrontendReadWriteTransactionTest {
40 private static final ClientIdentifier CLIENT_ID = ClientIdentifier.create(FrontendIdentifier.create(
41 MemberName.forName("mock"), FrontendType.forName("mock")), 0);
42 private static final LocalHistoryIdentifier HISTORY_ID = new LocalHistoryIdentifier(CLIENT_ID, 0);
43 private static final TransactionIdentifier TX_ID = new TransactionIdentifier(HISTORY_ID, 0);
45 private AbstractFrontendHistory mockHistory;
46 private ReadWriteShardDataTreeTransaction shardTransaction;
47 private DataTreeModification mockModification;
48 private ShardDataTreeTransactionParent mockParent;
49 private FrontendReadWriteTransaction openTx;
50 private ShardDataTreeCohort mockCohort;
54 mockHistory = mock(AbstractFrontendHistory.class);
55 mockParent = mock(ShardDataTreeTransactionParent.class);
56 mockModification = mock(DataTreeModification.class);
57 mockCohort = mock(ShardDataTreeCohort.class);
59 shardTransaction = new ReadWriteShardDataTreeTransaction(mockParent, TX_ID, mockModification);
60 openTx = FrontendReadWriteTransaction.createOpen(mockHistory, shardTransaction);
62 when(mockParent.finishTransaction(same(shardTransaction))).thenReturn(mockCohort);
65 private TransactionSuccess<?> handleRequest(final TransactionRequest<?> request) throws RequestException {
66 return openTx.doHandleRequest(request, new RequestEnvelope(request, 0, 0), 0);
70 public void testDuplicateModifyAbort() throws RequestException {
71 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
74 final TransactionRequest<?> abortReq = b.build();
75 assertNull(handleRequest(abortReq));
76 verify(mockParent).abortTransaction(same(shardTransaction), any(Runnable.class));
78 assertNull(handleRequest(abortReq));
79 verifyNoMoreInteractions(mockParent);
83 public void testDuplicateReady() throws RequestException {
84 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
87 final TransactionRequest<?> readyReq = b.build();
89 assertNotNull(handleRequest(readyReq));
90 verify(mockParent).finishTransaction(same(shardTransaction));
92 assertNotNull(handleRequest(readyReq));
93 verifyNoMoreInteractions(mockParent);
97 public void testDuplicateDirect() throws RequestException {
98 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
101 final TransactionRequest<?> readyReq = b.build();
103 assertNull(handleRequest(readyReq));
104 verify(mockParent).finishTransaction(same(shardTransaction));
106 assertNull(handleRequest(readyReq));
107 verifyNoMoreInteractions(mockParent);
111 public void testDuplicateCoordinated() throws RequestException {
112 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
115 final TransactionRequest<?> readyReq = b.build();
117 assertNull(handleRequest(readyReq));
118 verify(mockParent).finishTransaction(same(shardTransaction));
120 assertNull(handleRequest(readyReq));
121 verifyNoMoreInteractions(mockParent);
124 @Test(expected = IllegalStateException.class)
125 public void testReadAfterReady() throws RequestException {
126 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
129 final TransactionRequest<?> readyReq = b.build();
131 assertNotNull(handleRequest(readyReq));
132 verify(mockParent).finishTransaction(same(shardTransaction));
134 handleRequest(new ReadTransactionRequest(TX_ID, 0, mock(ActorRef.class), YangInstanceIdentifier.EMPTY, true));
137 @Test(expected = IllegalStateException.class)
138 public void testModifyAfterReady() throws RequestException {
139 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
142 final TransactionRequest<?> readyReq = b.build();
144 assertNotNull(handleRequest(readyReq));
145 verify(mockParent).finishTransaction(same(shardTransaction));
148 b.addModification(mock(TransactionModification.class));
149 handleRequest(b.build());
152 @Test(expected = IllegalStateException.class)
153 public void testReadAfterAbort() throws RequestException {
154 final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
157 final TransactionRequest<?> abortReq = b.build();
158 assertNull(handleRequest(abortReq));
159 verify(mockParent).abortTransaction(same(shardTransaction), any(Runnable.class));
161 handleRequest(new ReadTransactionRequest(TX_ID, 0, mock(ActorRef.class), YangInstanceIdentifier.EMPTY, true));