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 java.util.Arrays;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.stream.Collectors;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.mockito.Mock;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 public class InterfaceCacheDumpManagerImplTest implements NamingContextHelper, FutureProducer {
54 private static final String IFACE_0 = "iface-0";
55 private static final String IFACE_1 = "iface-1";
56 private static final String IFACE_2 = "iface-2";
57 private static final String IFACE_3 = "iface-3";
60 private FutureJVppCore jvpp;
62 private ReadContext ctx;
64 private MappingContext mappingContext;
66 private InstanceIdentifier<Interface> identifier;
67 private InstanceIdentifier<Interface> identifierThree;
68 private NamingContext namingContext;
69 private ModificationCache cache;
70 private InterfaceCacheDumpManagerImpl manager;
73 public void setUp() throws Exception {
75 namingContext = new NamingContext("interface-", "interface-context");
76 cache = new ModificationCache();
77 manager = new InterfaceCacheDumpManagerImpl(jvpp, namingContext);
78 when(ctx.getModificationCache()).thenReturn(cache);
79 when(ctx.getMappingContext()).thenReturn(mappingContext);
80 identifier = InstanceIdentifier.create(InterfacesState.class)
81 .child(Interface.class, new InterfaceKey(IFACE_0));
83 identifierThree = InstanceIdentifier.create(InterfacesState.class)
84 .child(Interface.class, new InterfaceKey(IFACE_3));
86 when(jvpp.swInterfaceDump(fullRequest())).thenReturn(future(fullReply()));
88 // this one is not in full dump
89 when(jvpp.swInterfaceDump(specificRequest(IFACE_3))).thenReturn(future(specificReplyThree()));
90 defineMapping(mappingContext, IFACE_0, 0, "interface-context");
91 defineMapping(mappingContext, IFACE_1, 1, "interface-context");
92 defineMapping(mappingContext, IFACE_2, 2, "interface-context");
93 defineMapping(mappingContext, IFACE_3, 3, "interface-context");
97 public void getInterfaces() throws Exception {
98 assertFalse(cache.containsKey(BY_NAME_INDEX_KEY));
99 final List<SwInterfaceDetails> interfaces = manager.getInterfaces(identifier, ctx).collect(Collectors.toList());
100 assertEquals(3, interfaces.size());
101 assertTrue(interfaces.contains(detailZero()));
102 assertTrue(interfaces.contains(detailOne()));
103 assertTrue(interfaces.contains(detailTwo()));
105 // first request must call jvpp
106 verify(jvpp, times(1)).swInterfaceDump(fullRequest());
107 assertTrue(cache.containsKey(BY_NAME_INDEX_KEY));
109 // then cached value should be returned
110 final List<SwInterfaceDetails> cachedInterfaces =
111 manager.getInterfaces(identifier, ctx).collect(Collectors.toList());
112 assertEquals(3, cachedInterfaces.size());
113 assertTrue(cachedInterfaces.contains(detailZero()));
114 assertTrue(cachedInterfaces.contains(detailOne()));
115 assertTrue(cachedInterfaces.contains(detailTwo()));
117 //verify that dump wasn't invoked again
118 verifyNoMoreInteractions(jvpp);
122 public void getInterfaceDetailFromCache() throws Exception {
123 final HashMap<Object, Object> cachedMap = new HashMap<>();
124 final SwInterfaceDetails detailZero = detailZero();
125 cachedMap.put(IFACE_0, detailZero);
126 cache.put(BY_NAME_INDEX_KEY, cachedMap);
127 when(jvpp.swInterfaceDump(specificRequest(IFACE_0))).thenReturn(future(specificReplyZero()));
128 final SwInterfaceDetails interfaceDetail = manager.getInterfaceDetail(identifier, ctx, IFACE_0);
129 assertEquals(detailZero, interfaceDetail);
131 // must not call jvpp, just get it from cache
132 verifyZeroInteractions(jvpp);
136 public void getInterfaceDetailNotInFullDump() throws Exception {
137 assertFalse(cache.containsKey(BY_NAME_INDEX_KEY));
138 final SwInterfaceDetails specificDetail = manager.getInterfaceDetail(identifierThree, ctx, IFACE_3);
139 assertEquals(detailThree(), specificDetail);
141 verify(jvpp, times(1)).swInterfaceDump(specificRequest(IFACE_3));
144 private SwInterfaceDetailsReplyDump fullReply() {
145 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
146 reply.swInterfaceDetails = Arrays.asList(detailZero(), detailOne(), detailTwo());
150 private static SwInterfaceDetails detailTwo() {
151 SwInterfaceDetails detail3 = new SwInterfaceDetails();
152 detail3.swIfIndex = 2;
153 detail3.interfaceName = IFACE_2.getBytes();
157 private static SwInterfaceDetails detailOne() {
158 SwInterfaceDetails detail2 = new SwInterfaceDetails();
159 detail2.swIfIndex = 1;
160 detail2.interfaceName = IFACE_1.getBytes();
164 private static SwInterfaceDetails detailThree() {
165 SwInterfaceDetails detail2 = new SwInterfaceDetails();
166 detail2.swIfIndex = 3;
167 detail2.interfaceName = IFACE_3.getBytes();
171 private static SwInterfaceDetails detailZero() {
172 SwInterfaceDetails detail1 = new SwInterfaceDetails();
173 detail1.swIfIndex = 0;
174 detail1.interfaceName = IFACE_0.getBytes();
178 private SwInterfaceDetailsReplyDump specificReplyThree() {
179 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
180 reply.swInterfaceDetails = Arrays.asList(detailThree());
184 private SwInterfaceDetailsReplyDump specificReplyZero() {
185 final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
186 reply.swInterfaceDetails = Arrays.asList(detailZero());
190 private static SwInterfaceDump specificRequest(final String ifaceName) {
191 final SwInterfaceDump specificRequest = new SwInterfaceDump();
192 specificRequest.nameFilterValid = 1;
193 specificRequest.nameFilter = ifaceName.getBytes();
194 return specificRequest;
197 private static SwInterfaceDump fullRequest() {
198 final SwInterfaceDump fullRequest = new SwInterfaceDump();
199 fullRequest.nameFilterValid = 0;
200 fullRequest.nameFilter = "".getBytes();