2 * Copyright (c) 2016 Cisco and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.fd.honeycomb.v3po.translate.v3po.vpp;
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;
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;
53 public class BridgeDomainCustomizerTest {
55 private static final byte ADD_OR_UPDATE_BD = (byte) 1;
56 private static final byte ZERO = 0;
59 private FutureJVpp api;
61 private WriteContext ctx;
63 private MappingContext mappingContext;
65 private BridgeDomainCustomizer customizer;
68 public void setUp() throws Exception {
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();
76 customizer = new BridgeDomainCustomizer(api, namingContext);
79 private BridgeDomain generateBridgeDomain(final String bdName) {
80 final byte arpTerm = 0;
82 final byte forward = 0;
85 return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf);
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()
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))
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());
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);
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);
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);
144 private void whenBridgeDomainAddDelThenFailure()
145 throws ExecutionException, InterruptedException, VppInvocationException {
146 doReturn(TestHelperUtils.<BridgeDomainAddDelReply>createFutureException()).when(api)
147 .bridgeDomainAddDel(any(BridgeDomainAddDel.class));
151 public void testAddBridgeDomain() throws Exception {
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));
158 whenBridgeDomainAddDelThenSuccess();
160 customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
162 verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
163 verify(mappingContext).put(getMappingIid(bdName, "test-instance"), getMapping(bdName, bdId).get());
167 public void testAddBridgeDomainFailed() throws Exception {
169 final String bdName = "bd1";
170 final BridgeDomain bd = generateBridgeDomain(bdName);
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));
176 whenBridgeDomainAddDelThenFailure();
179 customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
180 } catch (WriteFailedException.CreateFailedException e) {
181 verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
184 fail("WriteFailedException.CreateFailedException was expected");
188 public void testDeleteBridgeDomain() throws Exception {
190 final String bdName = "bd1";
191 final BridgeDomain bd = generateBridgeDomain(bdName);
192 doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
194 whenBridgeDomainAddDelThenSuccess();
196 customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
198 verifyBridgeDomainDeleteWasInvoked(bdId);
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"));
208 customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
209 } catch (IllegalArgumentException e) {
210 verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
213 fail("IllegalArgumentException was expected");
217 public void testDeleteBridgeDomainFailed() throws Exception {
219 final String bdName = "bd1";
220 final BridgeDomain bd = generateBridgeDomain(bdName);
221 doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
223 whenBridgeDomainAddDelThenFailure();
226 customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
227 } catch (WriteFailedException.DeleteFailedException e) {
228 verifyBridgeDomainDeleteWasInvoked(bdId);
232 fail("WriteFailedException.DeleteFailedException was expected");
236 public void testUpdateBridgeDomain() throws Exception {
238 final String bdName = "bd1";
239 doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
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;
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,
253 whenBridgeDomainAddDelThenSuccess();
256 .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), dataBefore, dataAfter, ctx);
257 verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId);
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"));
269 .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bdBefore, bdAfter, ctx);
270 } catch (IllegalArgumentException e) {
271 verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
274 fail("IllegalArgumentException was expected");
278 public void testUpdateBridgeDomainFailed() throws Exception {
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"));
285 whenBridgeDomainAddDelThenFailure();
289 .updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bdBefore, bdAfter, ctx);
290 } catch (WriteFailedException.UpdateFailedException e) {
291 verifyBridgeDomainAddOrUpdateWasInvoked(bdAfter, bdId);
294 fail("IllegalStateException was expected");