ff9c0cf9bdb244e9b7864400933f466b2fd86776
[honeycomb.git] / v3po / v3po2vpp / src / test / java / io / fd / honeycomb / v3po / translate / v3po / vpp / BridgeDomainCustomizerTest.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.v3po.translate.v3po.vpp;
18
19 import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23 import static org.mockito.Matchers.any;
24 import static org.mockito.Mockito.doReturn;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 import static org.mockito.MockitoAnnotations.initMocks;
30
31 import com.google.common.base.Optional;
32 import io.fd.honeycomb.v3po.translate.MappingContext;
33 import io.fd.honeycomb.v3po.translate.ModificationCache;
34 import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils;
35 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
36 import io.fd.honeycomb.v3po.translate.write.WriteContext;
37 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
38 import java.util.concurrent.CompletableFuture;
39 import java.util.concurrent.CompletionStage;
40 import java.util.concurrent.ExecutionException;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.mockito.ArgumentCaptor;
44 import org.mockito.Mock;
45 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
48 import org.openvpp.jvpp.VppInvocationException;
49 import org.openvpp.jvpp.dto.BridgeDomainAddDel;
50 import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
51 import org.openvpp.jvpp.future.FutureJVpp;
52
53 public class BridgeDomainCustomizerTest {
54
55     private static final byte ADD_OR_UPDATE_BD = (byte) 1;
56     private static final byte ZERO = 0;
57
58     @Mock
59     private FutureJVpp api;
60     @Mock
61     private WriteContext ctx;
62     @Mock
63     private MappingContext mappingContext;
64
65     private BridgeDomainCustomizer customizer;
66
67     @Before
68     public void setUp() throws Exception {
69         initMocks(this);
70         // TODO create base class for tests using vppApi
71         NamingContext namingContext = new NamingContext("generatedBDName", "test-instance");
72         final ModificationCache toBeReturned = new ModificationCache();
73         doReturn(toBeReturned).when(ctx).getModificationCache();
74         doReturn(mappingContext).when(ctx).getMappingContext();
75
76         customizer = new BridgeDomainCustomizer(api, namingContext);
77     }
78
79     private BridgeDomain generateBridgeDomain(final String bdName) {
80         final byte arpTerm = 0;
81         final byte flood = 1;
82         final byte forward = 0;
83         final byte learn = 1;
84         final byte uuf = 0;
85         return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf);
86     }
87
88     private BridgeDomain generateBridgeDomain(final String bdName, final int arpTerm, final int flood,
89                                               final int forward, final int learn, final int uuf) {
90         return new BridgeDomainBuilder()
91             .setName(bdName)
92             .setArpTermination(BridgeDomainTestUtils.intToBoolean(arpTerm))
93             .setFlood(BridgeDomainTestUtils.intToBoolean(flood))
94             .setForward(BridgeDomainTestUtils.intToBoolean(forward))
95             .setLearn(BridgeDomainTestUtils.intToBoolean(learn))
96             .setUnknownUnicastFlood(BridgeDomainTestUtils.intToBoolean(uuf))
97             .build();
98     }
99
100     private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId)
101         throws VppInvocationException {
102         final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
103         final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
104         final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
105         final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
106         final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
107
108         // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
109         ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
110         verify(api).bridgeDomainAddDel(argumentCaptor.capture());
111         final BridgeDomainAddDel actual = argumentCaptor.getValue();
112         assertEquals(arpTerm, actual.arpTerm);
113         assertEquals(flood, actual.flood);
114         assertEquals(forward, actual.forward);
115         assertEquals(learn, actual.learn);
116         assertEquals(uuf, actual.uuFlood);
117         assertEquals(ADD_OR_UPDATE_BD, actual.isAdd);
118         assertEquals(bdId, actual.bdId);
119     }
120
121     private void verifyBridgeDomainDeleteWasInvoked(final int bdId) throws VppInvocationException {
122         ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
123         verify(api).bridgeDomainAddDel(argumentCaptor.capture());
124         final BridgeDomainAddDel actual = argumentCaptor.getValue();
125         assertEquals(bdId, actual.bdId);
126         assertEquals(ZERO, actual.arpTerm);
127         assertEquals(ZERO, actual.flood);
128         assertEquals(ZERO, actual.forward);
129         assertEquals(ZERO, actual.learn);
130         assertEquals(ZERO, actual.uuFlood);
131         assertEquals(ZERO, actual.isAdd);
132     }
133
134     private void whenBridgeDomainAddDelThenSuccess()
135         throws ExecutionException, InterruptedException, VppInvocationException {
136         final CompletionStage<BridgeDomainAddDelReply> replyCS = mock(CompletionStage.class);
137         final CompletableFuture<BridgeDomainAddDelReply> replyFuture = mock(CompletableFuture.class);
138         when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
139         final BridgeDomainAddDelReply reply = new BridgeDomainAddDelReply();
140         when(replyFuture.get()).thenReturn(reply);
141         when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(replyCS);
142     }
143
144     private void whenBridgeDomainAddDelThenFailure()
145         throws ExecutionException, InterruptedException, VppInvocationException {
146         doReturn(TestHelperUtils.<BridgeDomainAddDelReply>createFutureException()).when(api)
147             .bridgeDomainAddDel(any(BridgeDomainAddDel.class));
148     }
149
150     @Test
151     public void testAddBridgeDomain() throws Exception {
152         final int bdId = 1;
153         final String bdName = "bd1";
154         final BridgeDomain bd = generateBridgeDomain(bdName);
155         doReturn(Optional.absent()).when(mappingContext)
156             .read(getMappingIid(bdName, "test-instance").firstIdentifierOf(Mappings.class));
157
158         whenBridgeDomainAddDelThenSuccess();
159
160         customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
161
162         verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
163         verify(mappingContext).put(getMappingIid(bdName, "test-instance"), getMapping(bdName, bdId).get());
164     }
165
166     @Test
167     public void testAddBridgeDomainFailed() throws Exception {
168         final int bdId = 1;
169         final String bdName = "bd1";
170         final BridgeDomain bd = generateBridgeDomain(bdName);
171
172         // Returning no Mappings for "test-instance" makes bdContext.containsName() return false
173         doReturn(Optional.absent()).when(mappingContext)
174             .read(getMappingIid(bdName, "test-instance").firstIdentifierOf(Mappings.class));
175
176         whenBridgeDomainAddDelThenFailure();
177
178         try {
179             customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
180         } catch (WriteFailedException.CreateFailedException e) {
181             verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
182             return;
183         }
184         fail("WriteFailedException.CreateFailedException  was expected");
185     }
186
187     @Test
188     public void testDeleteBridgeDomain() throws Exception {
189         final int bdId = 1;
190         final String bdName = "bd1";
191         final BridgeDomain bd = generateBridgeDomain(bdName);
192         doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
193
194         whenBridgeDomainAddDelThenSuccess();
195
196         customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
197
198         verifyBridgeDomainDeleteWasInvoked(bdId);
199     }
200
201     @Test
202     public void testDeleteUnknownBridgeDomain() throws Exception {
203         final String bdName = "bd1";
204         final BridgeDomain bd = generateBridgeDomain("bd1");
205         doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
206
207         try {
208             customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
209         } catch (IllegalArgumentException e) {
210             verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
211             return;
212         }
213         fail("IllegalArgumentException was expected");
214     }
215
216     @Test
217     public void testDeleteBridgeDomainFailed() throws Exception {
218         final int bdId = 1;
219         final String bdName = "bd1";
220         final BridgeDomain bd = generateBridgeDomain(bdName);
221         doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
222
223         whenBridgeDomainAddDelThenFailure();
224
225         try {
226             customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
227         } catch (WriteFailedException.DeleteFailedException e) {
228             verifyBridgeDomainDeleteWasInvoked(bdId);
229             return;
230         }
231
232         fail("WriteFailedException.DeleteFailedException was expected");
233     }
234
235     @Test
236     public void testUpdateBridgeDomain() throws Exception {
237         final int bdId = 1;
238         final String bdName = "bd1";
239         doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
240
241         final byte arpTermBefore = 1;
242         final byte floodBefore = 1;
243         final byte forwardBefore = 0;
244         final byte learnBefore = 1;
245         final byte uufBefore = 0;
246
247         final BridgeDomain dataBefore =
248             generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore);
249         final BridgeDomain dataAfter =
250             generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1,
251                 uufBefore ^ 1);
252
253         whenBridgeDomainAddDelThenSuccess();
254
255         customizer
256             .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), dataBefore, dataAfter, ctx);
257         verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId);
258     }
259
260     @Test
261     public void testUpdateUnknownBridgeDomain() throws Exception {
262         final String bdName = "bd1";
263         final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0);
264         final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0);
265         doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
266
267         try {
268             customizer
269                 .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bdBefore, bdAfter, ctx);
270         } catch (IllegalArgumentException e) {
271             verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
272             return;
273         }
274         fail("IllegalArgumentException was expected");
275     }
276
277     @Test
278     public void testUpdateBridgeDomainFailed() throws Exception {
279         final int bdId = 1;
280         final String bdName = "bd1";
281         final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0, 1, 0);
282         final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0, 1, 0);
283         doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
284
285         whenBridgeDomainAddDelThenFailure();
286
287         try {
288             customizer
289                 .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bdBefore, bdAfter, ctx);
290         } catch (WriteFailedException.UpdateFailedException e) {
291             verifyBridgeDomainAddOrUpdateWasInvoked(bdAfter, bdId);
292             return;
293         }
294         fail("IllegalStateException was expected");
295     }
296
297 }