HONEYCOMB-118: extend classifer model to support node names.
[honeycomb.git] / v3po / v3po2vpp / src / test / java / io / fd / honeycomb / translate / v3po / vppclassifier / ClassifyTableWriterTest.java
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 import static org.mockito.MockitoAnnotations.initMocks;
29
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;
54
55 public class ClassifyTableWriterTest {
56
57     private static final int TABLE_INDEX = 123;
58     private static final String TABLE_NAME = "table123";
59
60     @Mock
61     private FutureJVppCore api;
62     @Mock
63     private WriteContext writeContext;
64     @Mock
65     private MappingContext ctx;
66     @Mock
67     private VppClassifierContextManager classifierContext;
68
69     private ClassifyTableWriter customizer;
70
71     @Before
72     public void setUp() throws Exception {
73         initMocks(this);
74         customizer = new ClassifyTableWriter(api, classifierContext);
75         doReturn(ctx).when(writeContext).getMappingContext();
76     }
77
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();
89     }
90
91     private static InstanceIdentifier<ClassifyTable> getClassifyTableId(final String name) {
92         return InstanceIdentifier.create(VppClassifier.class)
93             .child(ClassifyTable.class, new ClassifyTableKey(name));
94     }
95
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));
102     }
103
104     private void whenClassifyAddDelTableThenFailure() throws ExecutionException, InterruptedException {
105         doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException()).when(api)
106             .classifyAddDelTable(any(ClassifyAddDelTable.class));
107     }
108
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);
122     }
123
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);
130     }
131
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;
142         request.mask =
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};
145         return request;
146     }
147
148     @Test
149     public void testCreate() throws Exception {
150         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
151         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
152
153         whenClassifyAddDelTableThenSuccess();
154
155         customizer.writeCurrentAttributes(id, classifyTable, writeContext);
156
157         verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
158         verify(classifierContext).addTable(TABLE_INDEX, classifyTable.getName(), classifyTable.getClassifierNode(), ctx);
159     }
160
161     @Test
162     public void testCreateFailed() throws Exception {
163         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
164         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
165
166         whenClassifyAddDelTableThenFailure();
167
168         try {
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);
175             return;
176         }
177         fail("WriteFailedException.CreateFailedException was expected");
178     }
179
180     @Test
181     public void testDelete() throws Exception {
182         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
183         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
184
185         when(classifierContext.containsTable(TABLE_NAME, ctx)).thenReturn(true);
186         when(classifierContext.getTableIndex(TABLE_NAME, ctx)).thenReturn(TABLE_INDEX);
187         whenClassifyAddDelTableThenSuccess();
188
189         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
190
191         verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
192     }
193
194     @Test
195     public void testDeleteFailed() throws Exception {
196         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
197         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
198
199         when(classifierContext.containsTable(TABLE_NAME, ctx)).thenReturn(true);
200         when(classifierContext.getTableIndex(TABLE_NAME, ctx)).thenReturn(TABLE_INDEX);
201         whenClassifyAddDelTableThenFailure();
202
203         try {
204             customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
205         } catch (WriteFailedException.DeleteFailedException e) {
206             assertTrue(e.getCause() instanceof VppBaseCallException);
207             verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
208             return;
209         }
210         fail("WriteFailedException.DeleteFailedException was expected");
211
212         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
213     }
214
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);
220     }
221 }