BUG-8507: Fix replayed directCommit() on reconnect
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / FrontendReadWriteTransactionTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.datastore;
9
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;
18
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;
37
38 public class FrontendReadWriteTransactionTest {
39
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);
44
45     private AbstractFrontendHistory mockHistory;
46     private ReadWriteShardDataTreeTransaction shardTransaction;
47     private DataTreeModification mockModification;
48     private ShardDataTreeTransactionParent mockParent;
49     private FrontendReadWriteTransaction openTx;
50     private ShardDataTreeCohort mockCohort;
51
52     @Before
53     public void setup() {
54         mockHistory = mock(AbstractFrontendHistory.class);
55         mockParent = mock(ShardDataTreeTransactionParent.class);
56         mockModification = mock(DataTreeModification.class);
57         mockCohort = mock(ShardDataTreeCohort.class);
58
59         shardTransaction = new ReadWriteShardDataTreeTransaction(mockParent, TX_ID, mockModification);
60         openTx = FrontendReadWriteTransaction.createOpen(mockHistory, shardTransaction);
61
62         when(mockParent.finishTransaction(same(shardTransaction))).thenReturn(mockCohort);
63     }
64
65     private TransactionSuccess<?> handleRequest(final TransactionRequest<?> request) throws RequestException {
66         return openTx.doHandleRequest(request, new RequestEnvelope(request, 0, 0), 0);
67     }
68
69     @Test
70     public void testDuplicateModifyAbort() throws RequestException {
71         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
72         b.setSequence(0);
73         b.setAbort();
74         final TransactionRequest<?> abortReq = b.build();
75         assertNull(handleRequest(abortReq));
76         verify(mockParent).abortTransaction(same(shardTransaction), any(Runnable.class));
77
78         assertNull(handleRequest(abortReq));
79         verifyNoMoreInteractions(mockParent);
80     }
81
82     @Test
83     public void testDuplicateReady() throws RequestException {
84         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
85         b.setSequence(0);
86         b.setReady();
87         final TransactionRequest<?> readyReq = b.build();
88
89         assertNotNull(handleRequest(readyReq));
90         verify(mockParent).finishTransaction(same(shardTransaction));
91
92         assertNotNull(handleRequest(readyReq));
93         verifyNoMoreInteractions(mockParent);
94     }
95
96     @Test
97     public void testDuplicateDirect() throws RequestException {
98         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
99         b.setSequence(0);
100         b.setCommit(false);
101         final TransactionRequest<?> readyReq = b.build();
102
103         assertNull(handleRequest(readyReq));
104         verify(mockParent).finishTransaction(same(shardTransaction));
105
106         assertNull(handleRequest(readyReq));
107         verifyNoMoreInteractions(mockParent);
108     }
109
110     @Test
111     public void testDuplicateCoordinated() throws RequestException {
112         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
113         b.setSequence(0);
114         b.setCommit(true);
115         final TransactionRequest<?> readyReq = b.build();
116
117         assertNull(handleRequest(readyReq));
118         verify(mockParent).finishTransaction(same(shardTransaction));
119
120         assertNull(handleRequest(readyReq));
121         verifyNoMoreInteractions(mockParent);
122     }
123
124     @Test(expected = IllegalStateException.class)
125     public void testReadAfterReady() throws RequestException {
126         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
127         b.setSequence(0);
128         b.setReady();
129         final TransactionRequest<?> readyReq = b.build();
130
131         assertNotNull(handleRequest(readyReq));
132         verify(mockParent).finishTransaction(same(shardTransaction));
133
134         handleRequest(new ReadTransactionRequest(TX_ID, 0, mock(ActorRef.class), YangInstanceIdentifier.EMPTY, true));
135     }
136
137     @Test(expected = IllegalStateException.class)
138     public void testModifyAfterReady() throws RequestException {
139         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
140         b.setSequence(0);
141         b.setReady();
142         final TransactionRequest<?> readyReq = b.build();
143
144         assertNotNull(handleRequest(readyReq));
145         verify(mockParent).finishTransaction(same(shardTransaction));
146
147         b.setSequence(1);
148         b.addModification(mock(TransactionModification.class));
149         handleRequest(b.build());
150     }
151
152     @Test(expected = IllegalStateException.class)
153     public void testReadAfterAbort() throws RequestException {
154         final ModifyTransactionRequestBuilder b = new ModifyTransactionRequestBuilder(TX_ID, mock(ActorRef.class));
155         b.setSequence(0);
156         b.setAbort();
157         final TransactionRequest<?> abortReq = b.build();
158         assertNull(handleRequest(abortReq));
159         verify(mockParent).abortTransaction(same(shardTransaction), any(Runnable.class));
160
161         handleRequest(new ReadTransactionRequest(TX_ID, 0, mock(ActorRef.class), YangInstanceIdentifier.EMPTY, true));
162     }
163 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.