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.translate.v3po.vppstate;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.Matchers.any;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.doReturn;
25 import static org.mockito.Mockito.when;
26 import static org.mockito.MockitoAnnotations.initMocks;
28 import com.google.common.base.Optional;
29 import com.google.common.collect.Iterables;
30 import com.google.common.collect.Multimap;
31 import io.fd.honeycomb.translate.MappingContext;
32 import io.fd.honeycomb.translate.ModificationCache;
33 import io.fd.honeycomb.translate.impl.read.GenericListReader;
34 import io.fd.honeycomb.translate.impl.read.GenericReader;
35 import io.fd.honeycomb.translate.read.ReadContext;
36 import io.fd.honeycomb.translate.read.ReadFailedException;
37 import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
38 import io.fd.honeycomb.translate.util.read.registry.CompositeReaderRegistryBuilder;
39 import io.fd.honeycomb.vpp.test.util.NamingContextHelper;
40 import io.fd.honeycomb.translate.vpp.util.NamingContext;
41 import io.fd.honeycomb.vpp.test.util.FutureProducer;
42 import java.util.Arrays;
43 import java.util.Collections;
44 import java.util.List;
45 import javax.annotation.Nonnull;
46 import org.junit.Before;
47 import org.junit.Ignore;
48 import org.junit.Test;
49 import org.mockito.Mock;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
65 import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails;
66 import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump;
67 import io.fd.vpp.jvpp.core.dto.BridgeDomainDump;
68 import io.fd.vpp.jvpp.core.dto.L2FibTableDump;
69 import io.fd.vpp.jvpp.core.dto.L2FibTableEntry;
70 import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump;
71 import io.fd.vpp.jvpp.core.dto.ShowVersion;
72 import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
73 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
75 public class VppStateTest implements FutureProducer, NamingContextHelper {
77 private static final String BD_CTX_NAME = "bd-test-instance";
79 private FutureJVppCore api;
81 private ReadContext ctx;
83 private MappingContext mappingContext;
85 private NamingContext bdContext;
87 private ReaderRegistry readerRegistry;
89 private static InstanceIdentifier<BridgeDomains> bridgeDomainsId;
92 * Create root VppState reader with all its children wired.
94 private static ReaderRegistry getVppStateReader(@Nonnull final FutureJVppCore jVpp,
95 @Nonnull final NamingContext bdContext) {
96 final CompositeReaderRegistryBuilder registry = new CompositeReaderRegistryBuilder();
98 // VppState(Structural)
99 final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
100 registry.addStructuralReader(vppStateId, VppStateBuilder.class);
102 registry.add(new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)));
103 // BridgeDomains(Structural)
104 bridgeDomainsId = vppStateId.child(BridgeDomains.class);
105 registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class);
107 registry.add(getBridgeDomainReader(jVpp, bdContext));
108 return registry.build();
111 private static GenericListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> getBridgeDomainReader(
112 final @Nonnull FutureJVppCore jVpp, final @Nonnull NamingContext bdContext) {
113 final InstanceIdentifier<BridgeDomain> bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class);
114 return new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdContext));
118 public void setUp() throws Exception {
120 final ModificationCache cache = new ModificationCache();
121 doReturn(cache).when(ctx).getModificationCache();
122 doReturn(mappingContext).when(ctx).getMappingContext();
124 bdContext = new NamingContext("generatedBdName", BD_CTX_NAME);
125 readerRegistry = getVppStateReader(api, bdContext);
128 private static Version getVersion() {
129 return new VersionBuilder()
131 .setBuildDirectory("1")
137 private void whenShowVersionThenReturn(final Version version) {
138 final ShowVersionReply reply = new ShowVersionReply();
139 reply.buildDate = version.getBuildDate().getBytes();
140 reply.program = version.getName().getBytes();
141 reply.version = version.getBranch().getBytes();
142 reply.buildDirectory = version.getBuildDirectory().getBytes();
143 when(api.showVersion(any(ShowVersion.class))).thenReturn(future(reply));
146 private void whenL2FibTableDumpThenReturn(final List<L2FibTableEntry> entryList) {
147 final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump();
148 reply.l2FibTableEntry = entryList;
149 when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(future(reply));
152 private void whenBridgeDomainDumpThenReturn(final List<BridgeDomainDetails> bdList) {
153 final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump();
154 reply.bridgeDomainDetails = bdList;
156 doAnswer(invocation -> {
157 BridgeDomainDump request = (BridgeDomainDump) invocation.getArguments()[0];
158 if (request.bdId == -1) {
159 reply.bridgeDomainDetails = bdList;
161 reply.bridgeDomainDetails = Collections.singletonList(bdList.get(request.bdId));
163 return future(reply);
164 }).when(api).bridgeDomainDump(any(BridgeDomainDump.class));
168 public void testReadAll() throws Exception {
169 final Version version = getVersion();
170 whenShowVersionThenReturn(version);
172 final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails();
173 final BridgeDomainDetails bridgeDomainDetails2 = new BridgeDomainDetails();
174 bridgeDomainDetails2.bdId = 1;
176 final List<BridgeDomainDetails> bdList = Arrays.asList(bridgeDomainDetails, bridgeDomainDetails2);
177 mockBdMapping(bridgeDomainDetails, "bd1");
178 mockBdMapping(bridgeDomainDetails2, "bd2");
180 whenBridgeDomainDumpThenReturn(bdList);
182 final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects =
183 readerRegistry.readAll(ctx);
184 assertEquals(dataObjects.size(), 1);
185 final VppState dataObject =
186 (VppState) Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
187 assertEquals(version, dataObject.getVersion());
188 assertEquals(2, dataObject.getBridgeDomains().getBridgeDomain().size());
192 public void testReadSpecific() throws Exception {
193 final Version version = getVersion();
194 whenShowVersionThenReturn(version);
195 whenBridgeDomainDumpThenReturn(Collections.emptyList());
197 final Optional<? extends DataObject> read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx);
198 assertTrue(read.isPresent());
199 assertEquals(version, ((VppState) read.get()).getVersion());
203 public void testReadBridgeDomains() throws Exception {
204 final Version version = getVersion();
205 whenShowVersionThenReturn(version);
206 final BridgeDomainDetails details = new BridgeDomainDetails();
207 whenBridgeDomainDumpThenReturn(Collections.singletonList(details));
209 mockBdMapping(details, "bdn1");
210 VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
212 Optional<? extends DataObject> read =
213 readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class), ctx);
214 assertTrue(read.isPresent());
215 assertEquals(readRoot.getBridgeDomains(), read.get());
219 * L2fib does not have a dedicated reader, relying on auto filtering
222 @Ignore("L2 FIB was moved to dedicated customizer. TODO: add infra test that covers such case")
223 @SuppressWarnings("unchecked")
224 public void testReadL2Fib() throws Exception {
225 final BridgeDomainDetails bd = new BridgeDomainDetails();
227 final String bdName = "bdn1";
228 mockBdMapping(bd, bdName);
229 defineMapping(mappingContext, "eth1", 0, "ifc-test-instance");
231 whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
232 final L2FibTableEntry l2FibEntry = new L2FibTableEntry();
234 l2FibEntry.mac = 0x0605040302010000L;
235 whenL2FibTableDumpThenReturn(Collections.singletonList(l2FibEntry));
237 // Deep child without a dedicated reader with specific l2fib key
238 final InstanceIdentifier<? extends DataObject> idExisting =
239 InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
240 BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class)
241 .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("01:02:03:04:05:06")));
242 Optional<? extends DataObject> read =
243 readerRegistry.read(idExisting, ctx);
244 assertTrue(read.isPresent());
246 // non existing l2fib
247 final InstanceIdentifier<? extends DataObject> idNonExisting =
248 InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
249 BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2FibTable.class)
250 .child(L2FibEntry.class, new L2FibEntryKey(new PhysAddress("FF:FF:FF:04:05:06")));
251 read = readerRegistry.read(idNonExisting, ctx);
252 assertFalse(read.isPresent());
255 private void mockBdMapping(final BridgeDomainDetails bd, final String bdName) {
256 defineMapping(mappingContext, bdName, bd.bdId, BD_CTX_NAME);
260 public void testReadBridgeDomainAll() throws Exception {
261 final Version version = getVersion();
262 whenShowVersionThenReturn(version);
263 final BridgeDomainDetails details = new BridgeDomainDetails();
264 whenBridgeDomainDumpThenReturn(Collections.singletonList(details));
265 mockBdMapping(details, "bd2");
267 VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
269 final GenericListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
270 getBridgeDomainReader(api, bdContext);
272 final List<BridgeDomain> read =
273 bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
274 BridgeDomain.class), ctx);
276 assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read);
280 public void testReadBridgeDomain() throws Exception {
281 final BridgeDomainDetails bd = new BridgeDomainDetails();
283 final String bdName = "bdn1";
284 mockBdMapping(bd, bdName);
286 whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
287 whenShowVersionThenReturn(getVersion());
289 VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
291 final Optional<? extends DataObject> read =
292 readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
293 BridgeDomain.class, new BridgeDomainKey(bdName)), ctx);
295 assertTrue(read.isPresent());
296 assertEquals(readRoot.getBridgeDomains().getBridgeDomain().stream().filter(
297 input -> input.getKey().getName().equals(bdName)).findFirst().get(),
301 @Test(expected = ReadFailedException.class)
302 public void testReadBridgeDomainNotExisting() throws Exception {
303 final String nonExistingBdName = "NOT EXISTING";
304 noMappingDefined(mappingContext, nonExistingBdName, BD_CTX_NAME);
306 readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
307 BridgeDomain.class, new BridgeDomainKey(nonExistingBdName)), ctx);
311 public void testReadVersion() throws Exception {
312 whenShowVersionThenReturn(getVersion());
313 whenBridgeDomainDumpThenReturn(Collections.emptyList());
314 VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
316 Optional<? extends DataObject> read =
317 readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx);
318 assertTrue(read.isPresent());
319 assertEquals(readRoot.getVersion(), read.get());