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.times;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 import static org.mockito.MockitoAnnotations.initMocks;
30 import io.fd.honeycomb.translate.MappingContext;
31 import io.fd.honeycomb.translate.v3po.test.TestHelperUtils;
32 import io.fd.honeycomb.translate.write.WriteContext;
33 import io.fd.honeycomb.translate.write.WriteFailedException;
34 import java.util.concurrent.CompletableFuture;
35 import java.util.concurrent.ExecutionException;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.mockito.ArgumentCaptor;
39 import org.mockito.Mock;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.PacketHandlingAction;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNode;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNodeName;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableKey;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.openvpp.jvpp.VppBaseCallException;
50 import org.openvpp.jvpp.core.dto.ClassifyAddDelTable;
51 import org.openvpp.jvpp.core.dto.ClassifyAddDelTableReply;
52 import org.openvpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply;
53 import org.openvpp.jvpp.core.future.FutureJVppCore;
55 public class ClassifyTableWriterTest {
57 private static final int TABLE_INDEX = 123;
58 private static final String TABLE_NAME = "table123";
61 private FutureJVppCore api;
63 private WriteContext writeContext;
65 private MappingContext ctx;
67 private VppClassifierContextManager classifierContext;
69 private ClassifyTableWriter customizer;
72 public void setUp() throws Exception {
74 customizer = new ClassifyTableWriter(api, classifierContext);
75 doReturn(ctx).when(writeContext).getMappingContext();
78 private static ClassifyTable generateClassifyTable(final String name) {
79 final ClassifyTableBuilder builder = new ClassifyTableBuilder();
80 builder.setName(name);
81 builder.setClassifierNode(new VppNodeName("ip4-classifier"));
82 builder.setKey(new ClassifyTableKey(name));
83 builder.setSkipNVectors(0L);
84 builder.setNbuckets(2L);
85 builder.setMemorySize(2L << 20);
86 builder.setMissNext(new VppNode(PacketHandlingAction.Permit));
87 builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"));
88 return builder.build();
91 private static InstanceIdentifier<ClassifyTable> getClassifyTableId(final String name) {
92 return InstanceIdentifier.create(VppClassifier.class)
93 .child(ClassifyTable.class, new ClassifyTableKey(name));
96 private void whenClassifyAddDelTableThenSuccess() throws ExecutionException, InterruptedException {
97 final CompletableFuture<ClassifyAddDelTableReply> replyFuture = new CompletableFuture<>();
98 final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply();
99 reply.newTableIndex = TABLE_INDEX;
100 replyFuture.complete(reply);
101 doReturn(replyFuture).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class));
104 private void whenClassifyAddDelTableThenFailure() throws ExecutionException, InterruptedException {
105 doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException()).when(api)
106 .classifyAddDelTable(any(ClassifyAddDelTable.class));
109 private void verifyClassifyAddDelTableAddWasInvoked(final ClassifyAddDelTable expected) {
110 ArgumentCaptor<ClassifyAddDelTable> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelTable.class);
111 verify(api).classifyAddDelTable(argumentCaptor.capture());
112 final ClassifyAddDelTable actual = argumentCaptor.getValue();
113 assertEquals(expected.isAdd, actual.isAdd);
114 assertEquals(~0, actual.tableIndex);
115 assertEquals(expected.nbuckets, actual.nbuckets);
116 assertEquals(expected.memorySize, actual.memorySize);
117 assertEquals(expected.skipNVectors, actual.skipNVectors);
118 assertEquals(expected.matchNVectors, actual.matchNVectors);
119 assertEquals(expected.nextTableIndex, actual.nextTableIndex);
120 assertEquals(expected.missNextIndex, actual.missNextIndex);
121 assertArrayEquals(expected.mask, actual.mask);
124 private void verifyClassifyAddDelTableDeleteWasInvoked(final ClassifyAddDelTable expected) {
125 ArgumentCaptor<ClassifyAddDelTable> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelTable.class);
126 verify(api).classifyAddDelTable(argumentCaptor.capture());
127 final ClassifyAddDelTable actual = argumentCaptor.getValue();
128 assertEquals(expected.isAdd, actual.isAdd);
129 assertEquals(expected.tableIndex, actual.tableIndex);
132 private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) {
133 final ClassifyAddDelTable request = new ClassifyAddDelTable();
134 request.isAdd = isAdd;
135 request.tableIndex = tableIndex;
136 request.nbuckets = 2;
137 request.memorySize = 2 << 20;
138 request.skipNVectors = 0;
139 request.matchNVectors = 1;
140 request.nextTableIndex = ~0;
141 request.missNextIndex = ~0;
143 new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
144 (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00};
149 public void testCreate() throws Exception {
150 final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
151 final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
153 whenClassifyAddDelTableThenSuccess();
155 customizer.writeCurrentAttributes(id, classifyTable, writeContext);
157 verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
158 verify(classifierContext).addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), ctx);
162 public void testCreateFailed() throws Exception {
163 final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
164 final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
166 whenClassifyAddDelTableThenFailure();
169 customizer.writeCurrentAttributes(id, classifyTable, writeContext);
170 } catch (WriteFailedException.CreateFailedException e) {
171 assertTrue(e.getCause() instanceof VppBaseCallException);
172 verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
173 verify(classifierContext, times(0))
174 .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), ctx);
177 fail("WriteFailedException.CreateFailedException was expected");
181 public void testDelete() throws Exception {
182 final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
183 final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
185 when(classifierContext.containsTable(TABLE_NAME, ctx)).thenReturn(true);
186 when(classifierContext.getTableIndex(TABLE_NAME, ctx)).thenReturn(TABLE_INDEX);
187 whenClassifyAddDelTableThenSuccess();
189 customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
191 verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
195 public void testDeleteFailed() throws Exception {
196 final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
197 final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
199 when(classifierContext.containsTable(TABLE_NAME, ctx)).thenReturn(true);
200 when(classifierContext.getTableIndex(TABLE_NAME, ctx)).thenReturn(TABLE_INDEX);
201 whenClassifyAddDelTableThenFailure();
204 customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
205 } catch (WriteFailedException.DeleteFailedException e) {
206 assertTrue(e.getCause() instanceof VppBaseCallException);
207 verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
210 fail("WriteFailedException.DeleteFailedException was expected");
212 customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
215 @Test(expected = UnsupportedOperationException.class)
216 public void testUpdate() throws Exception {
217 final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME);
218 final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
219 customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext);