Migrate netconf users of submit() to commit()
[netconf.git] / netconf / sal-netconf-connector / src / test / java / org / opendaylight / netconf / sal / connect / netconf / sal / tx / TxChainTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
10
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Mockito.never;
13 import static org.mockito.Mockito.verify;
14 import static org.mockito.Mockito.when;
15
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.mockito.ArgumentCaptor;
19 import org.mockito.Mock;
20 import org.mockito.MockitoAnnotations;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
22 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
25 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
26
27 public class TxChainTest {
28
29     @Mock
30     private DOMDataBroker broker;
31     @Mock
32     private TransactionChainListener listener;
33     @Mock
34     private DOMDataReadOnlyTransaction readOnlyTx;
35     @Mock
36     private AbstractWriteTx writeOnlyTx1;
37     @Mock
38     private AbstractWriteTx writeOnlyTx2;
39     @Mock
40     private AbstractWriteTx writeOnlyTx3;
41     @Mock
42     private AutoCloseable registration1;
43     @Mock
44     private AutoCloseable registration2;
45     @Mock
46     private AutoCloseable registration3;
47     private final ArgumentCaptor<TxListener> captor = ArgumentCaptor.forClass(TxListener.class);
48     private TxChain chain;
49
50     @Before
51     public void setUp() throws Exception {
52         MockitoAnnotations.initMocks(this);
53         when(broker.newReadOnlyTransaction()).thenReturn(readOnlyTx);
54         when(broker.newWriteOnlyTransaction()).thenReturn(writeOnlyTx1)
55                 .thenReturn(writeOnlyTx2).thenReturn(writeOnlyTx3);
56         when(writeOnlyTx1.addListener(any())).thenReturn(registration1);
57         when(writeOnlyTx2.addListener(any())).thenReturn(registration2);
58         when(writeOnlyTx3.addListener(any())).thenReturn(registration3);
59         chain = new TxChain(broker, listener);
60     }
61
62     @Test()
63     public void testNewReadOnlyTransactionPrevSubmitted() throws Exception {
64         chain.newWriteOnlyTransaction();
65         verify(writeOnlyTx1).addListener(captor.capture());
66         captor.getValue().onTransactionSubmitted(writeOnlyTx1);
67         chain.newReadOnlyTransaction();
68     }
69
70     @Test(expected = IllegalStateException.class)
71     public void testNewReadOnlyTransactionPrevNotSubmitted() throws Exception {
72         chain.newWriteOnlyTransaction();
73         chain.newReadOnlyTransaction();
74     }
75
76     @Test
77     public void testNewReadWriteTransactionPrevSubmitted() throws Exception {
78         chain.newReadWriteTransaction();
79         verify(writeOnlyTx1).addListener(captor.capture());
80         captor.getValue().onTransactionSubmitted(writeOnlyTx1);
81         chain.newReadWriteTransaction();
82     }
83
84     @Test(expected = IllegalStateException.class)
85     public void testNewReadWriteTransactionPrevNotSubmitted() throws Exception {
86         chain.newReadWriteTransaction();
87         chain.newReadWriteTransaction();
88     }
89
90     @Test
91     public void testNewWriteOnlyTransactionPrevSubmitted() throws Exception {
92         chain.newWriteOnlyTransaction();
93         verify(writeOnlyTx1).addListener(captor.capture());
94         captor.getValue().onTransactionSubmitted(writeOnlyTx1);
95         chain.newWriteOnlyTransaction();
96     }
97
98     @Test(expected = IllegalStateException.class)
99     public void testNewWriteOnlyTransactionPrevNotSubmitted() throws Exception {
100         chain.newWriteOnlyTransaction();
101         chain.newWriteOnlyTransaction();
102     }
103
104     @Test(expected = TransactionChainClosedException.class)
105     public void testCloseAfterFinished() throws Exception {
106         chain.close();
107         verify(listener).onTransactionChainSuccessful(chain);
108         chain.newReadOnlyTransaction();
109     }
110
111     @Test
112     public void testChainFail() throws Exception {
113         final AbstractWriteTx writeTx = chain.newWriteOnlyTransaction();
114         verify(writeOnlyTx1).addListener(captor.capture());
115         writeTx.commit();
116         final TransactionCommitFailedException cause = new TransactionCommitFailedException("fail");
117         captor.getValue().onTransactionFailed(writeOnlyTx1, cause);
118         verify(registration1).close();
119         verify(listener).onTransactionChainFailed(chain, writeOnlyTx1, cause);
120     }
121
122     @Test
123     public void testChainSuccess() throws Exception {
124         final AbstractWriteTx writeTx = chain.newWriteOnlyTransaction();
125         chain.close();
126         verify(writeOnlyTx1).addListener(captor.capture());
127         writeTx.commit();
128         captor.getValue().onTransactionSuccessful(writeOnlyTx1);
129         verify(registration1).close();
130         verify(listener).onTransactionChainSuccessful(chain);
131     }
132
133     @Test
134     public void testCancel() throws Exception {
135         final AbstractWriteTx writeTx = chain.newWriteOnlyTransaction();
136         verify(writeOnlyTx1).addListener(captor.capture());
137         writeTx.cancel();
138         captor.getValue().onTransactionCancelled(writeOnlyTx1);
139         chain.newWriteOnlyTransaction();
140     }
141
142     @Test
143     public void testMultiplePendingTransactions() throws Exception {
144         //create 1st tx
145         final AbstractWriteTx writeTx1 = chain.newWriteOnlyTransaction();
146         final ArgumentCaptor<TxListener> captor1 = ArgumentCaptor.forClass(TxListener.class);
147         verify(writeOnlyTx1).addListener(captor1.capture());
148         //submit 1st tx
149         writeTx1.commit();
150         captor1.getValue().onTransactionSubmitted(writeOnlyTx1);
151
152         //create 2nd tx
153         final AbstractWriteTx writeTx2 = chain.newWriteOnlyTransaction();
154         final ArgumentCaptor<TxListener> captor2 = ArgumentCaptor.forClass(TxListener.class);
155         verify(writeTx2).addListener(captor2.capture());
156         //submit 2nd tx
157         writeTx2.commit();
158         captor2.getValue().onTransactionSubmitted(writeOnlyTx2);
159
160         //create 3rd tx
161         final AbstractWriteTx writeTx3 = chain.newWriteOnlyTransaction();
162         final ArgumentCaptor<TxListener> captor3 = ArgumentCaptor.forClass(TxListener.class);
163         verify(writeTx3).addListener(captor3.capture());
164         //cancel 3rd tx
165         writeTx3.cancel();
166         captor3.getValue().onTransactionCancelled(writeOnlyTx3);
167
168         //close chain
169         chain.close();
170
171         //complete first two transactions successfully
172         captor1.getValue().onTransactionSuccessful(writeOnlyTx1);
173         captor2.getValue().onTransactionSuccessful(writeOnlyTx2);
174
175         verify(registration1).close();
176         verify(registration2).close();
177         verify(registration3).close();
178         verify(listener).onTransactionChainSuccessful(chain);
179     }
180
181     @Test
182     public void testMultiplePendingTransactionsFail() throws Exception {
183         //create 1st tx
184         final AbstractWriteTx writeTx1 = chain.newWriteOnlyTransaction();
185         final ArgumentCaptor<TxListener> captor1 = ArgumentCaptor.forClass(TxListener.class);
186         verify(writeOnlyTx1).addListener(captor1.capture());
187         //submit 1st tx
188         writeTx1.commit();
189         captor1.getValue().onTransactionSubmitted(writeOnlyTx1);
190
191         //create 2nd tx
192         final AbstractWriteTx writeTx2 = chain.newWriteOnlyTransaction();
193         final ArgumentCaptor<TxListener> captor2 = ArgumentCaptor.forClass(TxListener.class);
194         verify(writeTx2).addListener(captor2.capture());
195         //submit 2nd tx
196         writeTx2.commit();
197         captor2.getValue().onTransactionSubmitted(writeOnlyTx2);
198
199         //create 3rd tx
200         final AbstractWriteTx writeTx3 = chain.newWriteOnlyTransaction();
201         final ArgumentCaptor<TxListener> captor3 = ArgumentCaptor.forClass(TxListener.class);
202         verify(writeTx3).addListener(captor3.capture());
203
204         chain.close();
205
206         //fail 1st transaction
207         final Exception cause1 = new Exception("fail");
208         captor1.getValue().onTransactionFailed(writeOnlyTx1, cause1);
209         //current unsubmitted transaction should be cancelled
210         verify(writeTx3).cancel();
211         captor3.getValue().onTransactionCancelled(writeTx3);
212         //2nd transaction success
213         captor2.getValue().onTransactionSuccessful(writeOnlyTx2);
214
215         verify(registration1).close();
216         verify(registration2).close();
217         verify(registration3).close();
218         verify(listener).onTransactionChainFailed(chain, writeOnlyTx1, cause1);
219         // 1 transaction failed, onTransactionChainSuccessful must not be called
220         verify(listener, never()).onTransactionChainSuccessful(chain);
221     }
222 }