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.vppclassifier;
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
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.verify;
27 import static org.mockito.Mockito.when;
28 import static org.mockito.MockitoAnnotations.initMocks;
30 import com.google.common.base.Optional;
31 import io.fd.honeycomb.translate.MappingContext;
32 import io.fd.honeycomb.translate.v3po.test.TestHelperUtils;
33 import io.fd.honeycomb.translate.write.WriteContext;
34 import io.fd.honeycomb.translate.write.WriteFailedException;
35 import java.util.concurrent.CompletableFuture;
36 import java.util.concurrent.ExecutionException;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.Mock;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.OpaqueIndex;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.PacketHandlingAction;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNode;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNodeName;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySession;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySessionBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySessionKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableKey;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.openvpp.jvpp.VppBaseCallException;
54 import org.openvpp.jvpp.core.dto.ClassifyAddDelSession;
55 import org.openvpp.jvpp.core.dto.ClassifyAddDelSessionReply;
56 import org.openvpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply;
57 import org.openvpp.jvpp.core.future.FutureJVppCore;
59 public class ClassifySessionWriterTest {
61 private static final int TABLE_INDEX = 123;
62 private static final String TABLE_NAME = "table123";
65 private FutureJVppCore api;
67 private WriteContext writeContext;
69 private MappingContext ctx;
71 private VppClassifierContextManager classfierContext;
73 private ClassifySessionWriter customizer;
74 private static final int SESSION_INDEX = 456;
77 public void setUp() throws Exception {
79 doReturn(ctx).when(writeContext).getMappingContext();
80 customizer = new ClassifySessionWriter(api, classfierContext);
82 when(classfierContext.containsTable(TABLE_NAME, ctx)).thenReturn(true);
83 when(classfierContext.getTableIndex(TABLE_NAME, ctx)).thenReturn(TABLE_INDEX);
85 final ClassifyTable table = mock(ClassifyTable.class);
86 when(table.getClassifierNode()).thenReturn(new VppNodeName("ip4-classifier"));
87 when(writeContext.readAfter(any())).thenReturn(Optional.of(table));
88 when(writeContext.readBefore(any())).thenReturn(Optional.of(table));
91 private static ClassifySession generateClassifySession(final long opaqueIndex, final String match) {
92 final ClassifySessionBuilder builder = new ClassifySessionBuilder();
93 builder.setOpaqueIndex(new OpaqueIndex(opaqueIndex));
94 builder.setHitNext(new VppNode(PacketHandlingAction.Deny));
95 builder.setAdvance(123);
96 builder.setMatch(new HexString(match));
97 return builder.build();
100 private static InstanceIdentifier<ClassifySession> getClassifySessionId(final String tableName,
101 final String match) {
102 return InstanceIdentifier.create(VppClassifier.class)
103 .child(ClassifyTable.class, new ClassifyTableKey(tableName))
104 .child(ClassifySession.class, new ClassifySessionKey(new HexString(match)));
107 private void whenClassifyAddDelSessionThenSuccess() throws ExecutionException, InterruptedException {
108 final CompletableFuture<ClassifyAddDelSessionReply> replyFuture = new CompletableFuture<>();
109 replyFuture.complete(new ClassifyAddDelSessionReply());
110 doReturn(replyFuture).when(api).classifyAddDelSession(any(ClassifyAddDelSession.class));
113 private void whenClassifyAddDelSessionThenFailure() throws ExecutionException, InterruptedException {
114 doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException()).when(api)
115 .classifyAddDelSession(any(ClassifyAddDelSession.class));
118 private void verifyClassifyAddDelSessionWasInvoked(final ClassifyAddDelSession expected) {
119 ArgumentCaptor<ClassifyAddDelSession> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelSession.class);
120 verify(api).classifyAddDelSession(argumentCaptor.capture());
121 final ClassifyAddDelSession actual = argumentCaptor.getValue();
122 assertEquals(expected.opaqueIndex, actual.opaqueIndex);
123 assertEquals(expected.isAdd, actual.isAdd);
124 assertEquals(expected.tableIndex, actual.tableIndex);
125 assertEquals(expected.hitNextIndex, actual.hitNextIndex);
126 assertArrayEquals(expected.match, actual.match);
127 assertEquals(expected.advance, actual.advance);
130 private void verifyClassifyAddDelSessionDeleteWasInvoked(final ClassifyAddDelSession expected) {
131 ArgumentCaptor<ClassifyAddDelSession> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelSession.class);
132 verify(api).classifyAddDelSession(argumentCaptor.capture());
133 final ClassifyAddDelSession actual = argumentCaptor.getValue();
134 assertEquals(expected.opaqueIndex, actual.opaqueIndex);
135 assertEquals(expected.isAdd, actual.isAdd);
136 assertEquals(expected.tableIndex, actual.tableIndex);
139 private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex,
140 final int sessionIndex) {
141 final ClassifyAddDelSession request = new ClassifyAddDelSession();
142 request.isAdd = isAdd;
143 request.tableIndex = tableIndex;
144 request.opaqueIndex = sessionIndex;
145 request.hitNextIndex = 0;
146 request.advance = 123;
148 new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
149 (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00};
154 public void testCreate() throws Exception {
155 final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00";
156 final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match);
157 final InstanceIdentifier<ClassifySession> id = getClassifySessionId(TABLE_NAME, match);
159 whenClassifyAddDelSessionThenSuccess();
161 customizer.writeCurrentAttributes(id, classifySession, writeContext);
163 verifyClassifyAddDelSessionWasInvoked(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX));
167 public void testCreateFailed() throws Exception {
168 final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00";
169 final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match);
170 final InstanceIdentifier<ClassifySession> id = getClassifySessionId(TABLE_NAME, match);
172 whenClassifyAddDelSessionThenFailure();
175 customizer.writeCurrentAttributes(id, classifySession, writeContext);
176 } catch (WriteFailedException.CreateFailedException e) {
177 assertTrue(e.getCause() instanceof VppBaseCallException);
178 verifyClassifyAddDelSessionWasInvoked(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX));
181 fail("WriteFailedException.CreateFailedException was expected");
184 @Test(expected = UnsupportedOperationException.class)
185 public void testUpdate() throws Exception {
186 customizer.updateCurrentAttributes(null, null, null, writeContext);
190 public void testDelete() throws Exception {
191 final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00";
192 final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match);
193 final InstanceIdentifier<ClassifySession> id = getClassifySessionId(TABLE_NAME, match);
195 whenClassifyAddDelSessionThenSuccess();
197 customizer.deleteCurrentAttributes(id, classifySession, writeContext);
199 verifyClassifyAddDelSessionDeleteWasInvoked(
200 generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX));
204 public void testDeleteFailed() throws Exception {
205 final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00";
206 final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match);
207 final InstanceIdentifier<ClassifySession> id = getClassifySessionId(TABLE_NAME, match);
209 whenClassifyAddDelSessionThenFailure();
212 customizer.deleteCurrentAttributes(id, classifySession, writeContext);
213 } catch (WriteFailedException.DeleteFailedException e) {
214 assertTrue(e.getCause() instanceof VppBaseCallException);
215 verifyClassifyAddDelSessionDeleteWasInvoked(
216 generateClassifyAddDelSession((byte) 0, TABLE_INDEX, SESSION_INDEX));
219 fail("WriteFailedException.DeleteFailedException was expected");
221 customizer.deleteCurrentAttributes(id, classifySession, writeContext);