2 * Copyright (c) 2017 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.hc2vpp.v3po.interfacesstate.cache;
19 import static io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceCacheDumpManagerImpl.BY_NAME_INDEX_KEY;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.verifyNoMoreInteractions;
26 import static org.mockito.Mockito.verifyZeroInteractions;
27 import static org.mockito.Mockito.when;
28 import static org.mockito.MockitoAnnotations.initMocks;
30 import io.fd.hc2vpp.common.test.util.FutureProducer;
31 import io.fd.hc2vpp.common.test.util.NamingContextHelper;
32 import io.fd.hc2vpp.common.translate.util.NamingContext;
33 import io.fd.honeycomb.translate.MappingContext;
34 import io.fd.honeycomb.translate.ModificationCache;
35 import io.fd.honeycomb.translate.read.ReadContext;
36 import io.fd.jvpp.core.dto.SwInterfaceDetails;
37 import io.fd.jvpp.core.dto.SwInterfaceDetailsReplyDump;
38 import io.fd.jvpp.core.dto.SwInterfaceDump;
39 import io.fd.jvpp.core.future.FutureJVppCore;
40 import io.fd.jvpp.core.types.InterfaceIndex;
41 import java.util.Arrays;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.stream.Collectors;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.mockito.Mock;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 public class InterfaceCacheDumpManagerImplTest implements NamingContextHelper, FutureProducer {
55 private static final String IFACE_0 = "iface-0";
56 private static final String IFACE_1 = "iface-1";
57 private static final String IFACE_2 = "iface-2";
58 private static final String IFACE_3 = "iface-3";
61 private FutureJVppCore jvpp;
63 private ReadContext ctx;
65 private MappingContext mappingContext;
67 private InstanceIdentifier<Interface> identifier;
68 private InstanceIdentifier<Interface> identifierThree;
69 private NamingContext namingContext;
70 private ModificationCache cache;
71 private InterfaceCacheDumpManagerImpl manager;
74 public void setUp() throws Exception {
76 namingContext = new NamingContext("interface-", "interface-context");
77 cache = new ModificationCache();
78 manager = new InterfaceCacheDumpManagerImpl(jvpp, namingContext);
79 when(ctx.getModificationCache()).thenReturn(cache);
80 when(ctx.getMappingContext()).thenReturn(mappingContext);
81 identifier = InstanceIdentifier.create(InterfacesState.class)
82 .child(Interface.class, new InterfaceKey(IFACE_0));
84 identifierThree = InstanceIdentifier.create(InterfacesState.class)
85 .child(Interface.class, new InterfaceKey(IFACE_3));
87 when(jvpp.swInterfaceDump(fullRequest())).thenReturn(future(fullReply()));
89 // this one is not in full dump
90 when(jvpp.swInterfaceDump(specificRequest(IFACE_3))).thenReturn(future(specificReplyThree()));
91 defineMapping(mappingContext, IFACE_0, 0, "interface-context");
92 defineMapping(mappingContext, IFACE_1, 1, "interface-context");
93 defineMapping(mappingContext, IFACE_2, 2, "interface-context");
94 defineMapping(mappingContext, IFACE_3, 3, "interface-context");
98 public void getInterfaces() throws Exception {
99 assertFalse(cache.containsKey(BY_NAME_INDEX_KEY));
100 final List<SwInterfaceDetails> interfaces = manager.getInterfaces(identifier, ctx).collect(Collectors.toList());
101 assertEquals(3, interfaces.size());
102 assertTrue(interfaces.contains(detailZero()));
103 assertTrue(interfaces.contains(detailOne()));
104 assertTrue(interfaces.contains(detailTwo()));
106 // first request must call jvpp
107 verify(jvpp, times(1)).swInterfaceDump(fullRequest());
108 assertTrue(cache.containsKey(BY_NAME_INDEX_KEY));
110 // then cached value should be returned
111 final List<SwInterfaceDetails> cachedInterfaces =
112 manager.getInterfaces(identifier, ctx).collect(Collectors.toList());
113 assertEquals(3, cachedInterfaces.size());
114 assertTrue(cachedInterfaces.contains(detailZero()));
115 assertTrue(cachedInterfaces.contains(detailOne()));
116 assertTrue(cachedInterfaces.contains(detailTwo()));
118 //verify that dump wasn't invoked again
119 verifyNoMoreInteractions(jvpp);
123 public void getInterfaceDetailFromCache() throws Exception {
124 final HashMap<Object, Object> cachedMap = new HashMap<>();
125 final SwInterfaceDetails detailZero = detailZero();
126 cachedMap.put(IFACE_0, detailZero);
127 cache.put(BY_NAME_INDEX_KEY, cachedMap);
128 when(jvpp.swInterfaceDump(specificRequest(IFACE_0))).thenReturn(future(specificReplyZero()));
129 final SwInterfaceDetails interfaceDetail = manager.getInterfaceDetail(identifier, ctx, IFACE_0);
130 assertEquals(detailZero, interfaceDetail);
132 // must not call jvpp, just get it from cache
133 verifyZeroInteractions(jvpp);
137 public void getInterfaceDetailNotInFullDump() throws Exception {
138 assertFalse(cache.containsKey(BY_NAME_INDEX_KEY));
139 final SwInterfaceDetails specificDetail = manager.getInterfaceDetail(identifierThree, ctx, IFACE_3);
140 assertEquals(detailThree(), specificDetail);
142 verify(jvpp, times(1)).swInterfaceDump(specificRequest(IFACE_3));
145 private SwInterfaceDetailsReplyDump fullReply() {
146 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
147 reply.swInterfaceDetails = Arrays.asList(detailZero(), detailOne(), detailTwo());
151 private static SwInterfaceDetails detailTwo() {
152 SwInterfaceDetails detail3 = new SwInterfaceDetails();
153 detail3.swIfIndex = 2;
154 detail3.interfaceName = IFACE_2.getBytes();
158 private static SwInterfaceDetails detailOne() {
159 SwInterfaceDetails detail2 = new SwInterfaceDetails();
160 detail2.swIfIndex = 1;
161 detail2.interfaceName = IFACE_1.getBytes();
165 private static SwInterfaceDetails detailThree() {
166 SwInterfaceDetails detail2 = new SwInterfaceDetails();
167 detail2.swIfIndex = 3;
168 detail2.interfaceName = IFACE_3.getBytes();
172 private static SwInterfaceDetails detailZero() {
173 SwInterfaceDetails detail1 = new SwInterfaceDetails();
174 detail1.swIfIndex = 0;
175 detail1.interfaceName = IFACE_0.getBytes();
179 private SwInterfaceDetailsReplyDump specificReplyThree() {
180 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
181 reply.swInterfaceDetails = Arrays.asList(detailThree());
185 private SwInterfaceDetailsReplyDump specificReplyZero() {
186 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
187 reply.swInterfaceDetails = Arrays.asList(detailZero());
191 private static SwInterfaceDump specificRequest(final String ifaceName) {
192 final SwInterfaceDump specificRequest = new SwInterfaceDump();
193 specificRequest.swIfIndex = new InterfaceIndex();
194 specificRequest.swIfIndex.interfaceindex =~0;
195 specificRequest.nameFilterValid = 1;
196 specificRequest.nameFilter = ifaceName.getBytes();
197 return specificRequest;
200 private static SwInterfaceDump fullRequest() {
201 final SwInterfaceDump fullRequest = new SwInterfaceDump();
202 fullRequest.swIfIndex = new InterfaceIndex();
203 fullRequest.swIfIndex.interfaceindex = ~0;
204 fullRequest.nameFilterValid = 0;
205 fullRequest.nameFilter = "".getBytes();