af586221115c1df9bb56046c77317c9b615e7eb8
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2017 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.hc2vpp.v3po.interfacesstate.cache;
18
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;
29
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;
52
53 public class InterfaceCacheDumpManagerImplTest implements NamingContextHelper, FutureProducer {
54
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";
59
60     @Mock
61     private FutureJVppCore jvpp;
62     @Mock
63     private ReadContext ctx;
64     @Mock
65     private MappingContext mappingContext;
66
67     private InstanceIdentifier<Interface> identifier;
68     private InstanceIdentifier<Interface> identifierThree;
69     private NamingContext namingContext;
70     private ModificationCache cache;
71     private InterfaceCacheDumpManagerImpl manager;
72
73     @Before
74     public void setUp() throws Exception {
75         initMocks(this);
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));
83
84         identifierThree = InstanceIdentifier.create(InterfacesState.class)
85                 .child(Interface.class, new InterfaceKey(IFACE_3));
86
87         when(jvpp.swInterfaceDump(fullRequest())).thenReturn(future(fullReply()));
88
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");
95     }
96
97     @Test
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()));
105
106         // first request must call jvpp
107         verify(jvpp, times(1)).swInterfaceDump(fullRequest());
108         assertTrue(cache.containsKey(BY_NAME_INDEX_KEY));
109
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()));
117
118         //verify that dump wasn't invoked again
119         verifyNoMoreInteractions(jvpp);
120     }
121
122     @Test
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);
131
132         // must not call jvpp, just get it from cache
133         verifyZeroInteractions(jvpp);
134     }
135
136     @Test
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);
141
142         verify(jvpp, times(1)).swInterfaceDump(specificRequest(IFACE_3));
143     }
144
145     private SwInterfaceDetailsReplyDump fullReply() {
146         final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
147         reply.swInterfaceDetails = Arrays.asList(detailZero(), detailOne(), detailTwo());
148         return reply;
149     }
150
151     private static SwInterfaceDetails detailTwo() {
152         SwInterfaceDetails detail3 = new SwInterfaceDetails();
153         detail3.swIfIndex = 2;
154         detail3.interfaceName = IFACE_2.getBytes();
155         return detail3;
156     }
157
158     private static SwInterfaceDetails detailOne() {
159         SwInterfaceDetails detail2 = new SwInterfaceDetails();
160         detail2.swIfIndex = 1;
161         detail2.interfaceName = IFACE_1.getBytes();
162         return detail2;
163     }
164
165     private static SwInterfaceDetails detailThree() {
166         SwInterfaceDetails detail2 = new SwInterfaceDetails();
167         detail2.swIfIndex = 3;
168         detail2.interfaceName = IFACE_3.getBytes();
169         return detail2;
170     }
171
172     private static SwInterfaceDetails detailZero() {
173         SwInterfaceDetails detail1 = new SwInterfaceDetails();
174         detail1.swIfIndex = 0;
175         detail1.interfaceName = IFACE_0.getBytes();
176         return detail1;
177     }
178
179     private SwInterfaceDetailsReplyDump specificReplyThree() {
180         final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
181         reply.swInterfaceDetails = Arrays.asList(detailThree());
182         return reply;
183     }
184
185     private SwInterfaceDetailsReplyDump specificReplyZero() {
186         final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
187         reply.swInterfaceDetails = Arrays.asList(detailZero());
188         return reply;
189     }
190
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;
198     }
199
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();
206         return fullRequest;
207     }
208 }