c49767d9002723e571ef0b32f3f143ccc5a62389
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2016 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.honeycomb.translate.v3po.vppclassifier;
18
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
29 import io.fd.honeycomb.translate.v3po.test.TestHelperUtils;
30 import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
31 import io.fd.honeycomb.translate.write.WriteFailedException;
32 import java.util.concurrent.CompletableFuture;
33 import java.util.concurrent.ExecutionException;
34 import org.junit.Test;
35 import org.mockito.ArgumentCaptor;
36 import org.mockito.Mock;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.PacketHandlingAction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNode;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNodeName;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableKey;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.openvpp.jvpp.VppBaseCallException;
47 import org.openvpp.jvpp.core.dto.ClassifyAddDelTable;
48 import org.openvpp.jvpp.core.dto.ClassifyAddDelTableReply;
49 import org.openvpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply;
50
51 public class ClassifyTableWriterTest extends WriterCustomizerTest {
52
53     private static final int TABLE_INDEX = 123;
54     private static final String TABLE_NAME = "table123";
55
56     @Mock
57     private VppClassifierContextManager classifierContext;
58
59     private ClassifyTableWriter customizer;
60
61     @Override
62     public void setUp() throws Exception {
63         customizer = new ClassifyTableWriter(api, classifierContext);
64     }
65
66     private static ClassifyTable generateClassifyTable(final String name) {
67         final ClassifyTableBuilder builder = new ClassifyTableBuilder();
68         builder.setName(name);
69         builder.setClassifierNode(new VppNodeName("ip4-classifier"));
70         builder.setKey(new ClassifyTableKey(name));
71         builder.setSkipNVectors(0L);
72         builder.setNbuckets(2L);
73         builder.setMemorySize(2L << 20);
74         builder.setMissNext(new VppNode(PacketHandlingAction.Permit));
75         builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"));
76         return builder.build();
77     }
78
79     private static InstanceIdentifier<ClassifyTable> getClassifyTableId(final String name) {
80         return InstanceIdentifier.create(VppClassifier.class)
81             .child(ClassifyTable.class, new ClassifyTableKey(name));
82     }
83
84     private void whenClassifyAddDelTableThenSuccess() throws ExecutionException, InterruptedException {
85         final CompletableFuture<ClassifyAddDelTableReply> replyFuture = new CompletableFuture<>();
86         final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply();
87         reply.newTableIndex = TABLE_INDEX;
88         replyFuture.complete(reply);
89         doReturn(replyFuture).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class));
90     }
91
92     private void whenClassifyAddDelTableThenFailure() throws ExecutionException, InterruptedException {
93         doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException()).when(api)
94             .classifyAddDelTable(any(ClassifyAddDelTable.class));
95     }
96
97     private void verifyClassifyAddDelTableAddWasInvoked(final ClassifyAddDelTable expected) {
98         ArgumentCaptor<ClassifyAddDelTable> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelTable.class);
99         verify(api).classifyAddDelTable(argumentCaptor.capture());
100         final ClassifyAddDelTable actual = argumentCaptor.getValue();
101         assertEquals(expected.isAdd, actual.isAdd);
102         assertEquals(~0, actual.tableIndex);
103         assertEquals(expected.nbuckets, actual.nbuckets);
104         assertEquals(expected.memorySize, actual.memorySize);
105         assertEquals(expected.skipNVectors, actual.skipNVectors);
106         assertEquals(expected.matchNVectors, actual.matchNVectors);
107         assertEquals(expected.nextTableIndex, actual.nextTableIndex);
108         assertEquals(expected.missNextIndex, actual.missNextIndex);
109         assertArrayEquals(expected.mask, actual.mask);
110     }
111
112     private void verifyClassifyAddDelTableDeleteWasInvoked(final ClassifyAddDelTable expected) {
113         ArgumentCaptor<ClassifyAddDelTable> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelTable.class);
114         verify(api).classifyAddDelTable(argumentCaptor.capture());
115         final ClassifyAddDelTable actual = argumentCaptor.getValue();
116         assertEquals(expected.isAdd, actual.isAdd);
117         assertEquals(expected.tableIndex, actual.tableIndex);
118     }
119
120     private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) {
121         final ClassifyAddDelTable request = new ClassifyAddDelTable();
122         request.isAdd = isAdd;
123         request.tableIndex = tableIndex;
124         request.nbuckets = 2;
125         request.memorySize = 2 << 20;
126         request.skipNVectors = 0;
127         request.matchNVectors = 1;
128         request.nextTableIndex = ~0;
129         request.missNextIndex = ~0;
130         request.mask =
131             new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
132                 (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00};
133         return request;
134     }
135
136     @Test
137     public void testCreate() throws Exception {
138         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
139         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
140
141         whenClassifyAddDelTableThenSuccess();
142
143         customizer.writeCurrentAttributes(id, classifyTable, writeContext);
144
145         verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
146         verify(classifierContext)
147             .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext);
148     }
149
150     @Test
151     public void testCreateFailed() throws Exception {
152         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
153         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
154
155         whenClassifyAddDelTableThenFailure();
156
157         try {
158             customizer.writeCurrentAttributes(id, classifyTable, writeContext);
159         } catch (WriteFailedException.CreateFailedException e) {
160             assertTrue(e.getCause() instanceof VppBaseCallException);
161             verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
162             verify(classifierContext, times(0))
163                 .addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), mappingContext);
164             return;
165         }
166         fail("WriteFailedException.CreateFailedException was expected");
167     }
168
169     @Test
170     public void testDelete() throws Exception {
171         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
172         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
173
174         when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true);
175         when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX);
176         whenClassifyAddDelTableThenSuccess();
177
178         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
179
180         verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
181     }
182
183     @Test
184     public void testDeleteFailed() throws Exception {
185         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
186         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
187
188         when(classifierContext.containsTable(TABLE_NAME, mappingContext)).thenReturn(true);
189         when(classifierContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX);
190         whenClassifyAddDelTableThenFailure();
191
192         try {
193             customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
194         } catch (WriteFailedException.DeleteFailedException e) {
195             assertTrue(e.getCause() instanceof VppBaseCallException);
196             verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
197             return;
198         }
199         fail("WriteFailedException.DeleteFailedException was expected");
200
201         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
202     }
203
204     @Test(expected = UnsupportedOperationException.class)
205     public void testUpdate() throws Exception {
206         final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME);
207         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
208         customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext);
209     }
210 }