5a3717e5088133c60da035cd7a36f308c9b2f7a4
[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 io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMappingIid;
21 import static junit.framework.TestCase.assertTrue;
22 import static org.junit.Assert.assertArrayEquals;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.fail;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.eq;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.MockitoAnnotations.initMocks;
31
32 import com.google.common.base.Optional;
33 import io.fd.honeycomb.translate.MappingContext;
34 import io.fd.honeycomb.translate.v3po.test.TestHelperUtils;
35 import io.fd.honeycomb.translate.v3po.util.NamingContext;
36 import io.fd.honeycomb.translate.write.WriteContext;
37 import io.fd.honeycomb.translate.write.WriteFailedException;
38 import java.util.concurrent.CompletableFuture;
39 import java.util.concurrent.ExecutionException;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.Mock;
44 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.PacketHandlingAction;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppNode;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableBuilder;
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.ClassifyAddDelTable;
55 import org.openvpp.jvpp.core.dto.ClassifyAddDelTableReply;
56 import org.openvpp.jvpp.core.dto.L2InterfaceVlanTagRewriteReply;
57 import org.openvpp.jvpp.core.future.FutureJVppCore;
58
59 public class ClassifyTableWriterTest {
60
61     private static final int TABLE_INDEX = 123;
62     private static final String TABLE_NAME = "table123";
63
64     @Mock
65     private FutureJVppCore api;
66     @Mock
67     private WriteContext writeContext;
68     @Mock
69     private MappingContext mappingContext;
70
71     private NamingContext classifyTableContext;
72     private ClassifyTableWriter customizer;
73
74     @Before
75     public void setUp() throws Exception {
76         initMocks(this);
77         classifyTableContext = new NamingContext("generatedClassifyTableName", "test-instance");
78         doReturn(mappingContext).when(writeContext).getMappingContext();
79         customizer = new ClassifyTableWriter(api, classifyTableContext);
80     }
81
82     private static ClassifyTable generateClassifyTable(final String name) {
83         final ClassifyTableBuilder builder = new ClassifyTableBuilder();
84         builder.setName(name);
85         builder.setKey(new ClassifyTableKey(name));
86         builder.setSkipNVectors(0L);
87         builder.setNbuckets(2L);
88         builder.setMemorySize(2L << 20);
89         builder.setMissNext(new VppNode(PacketHandlingAction.Permit));
90         builder.setMask(new HexString("00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"));
91         return builder.build();
92     }
93
94     private static InstanceIdentifier<ClassifyTable> getClassifyTableId(final String name) {
95         return InstanceIdentifier.create(VppClassifier.class)
96             .child(ClassifyTable.class, new ClassifyTableKey(name));
97     }
98
99     private void whenClassifyAddDelTableThenSuccess() throws ExecutionException, InterruptedException {
100         final CompletableFuture<ClassifyAddDelTableReply> replyFuture = new CompletableFuture<>();
101         final ClassifyAddDelTableReply reply = new ClassifyAddDelTableReply();
102         reply.newTableIndex = TABLE_INDEX;
103         replyFuture.complete(reply);
104         doReturn(replyFuture).when(api).classifyAddDelTable(any(ClassifyAddDelTable.class));
105     }
106
107     private void whenClassifyAddDelTableThenFailure() throws ExecutionException, InterruptedException {
108         doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException()).when(api)
109             .classifyAddDelTable(any(ClassifyAddDelTable.class));
110     }
111
112     private void verifyClassifyAddDelTableAddWasInvoked(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(~0, actual.tableIndex);
118         assertEquals(expected.nbuckets, actual.nbuckets);
119         assertEquals(expected.memorySize, actual.memorySize);
120         assertEquals(expected.skipNVectors, actual.skipNVectors);
121         assertEquals(expected.matchNVectors, actual.matchNVectors);
122         assertEquals(expected.nextTableIndex, actual.nextTableIndex);
123         assertEquals(expected.missNextIndex, actual.missNextIndex);
124         assertArrayEquals(expected.mask, actual.mask);
125     }
126
127     private void verifyClassifyAddDelTableDeleteWasInvoked(final ClassifyAddDelTable expected) {
128         ArgumentCaptor<ClassifyAddDelTable> argumentCaptor = ArgumentCaptor.forClass(ClassifyAddDelTable.class);
129         verify(api).classifyAddDelTable(argumentCaptor.capture());
130         final ClassifyAddDelTable actual = argumentCaptor.getValue();
131         assertEquals(expected.isAdd, actual.isAdd);
132         assertEquals(expected.tableIndex, actual.tableIndex);
133     }
134
135     private static ClassifyAddDelTable generateClassifyAddDelTable(final byte isAdd, final int tableIndex) {
136         final ClassifyAddDelTable request = new ClassifyAddDelTable();
137         request.isAdd = isAdd;
138         request.tableIndex = tableIndex;
139         request.nbuckets = 2;
140         request.memorySize = 2 << 20;
141         request.skipNVectors = 0;
142         request.matchNVectors = 1;
143         request.nextTableIndex = ~0;
144         request.missNextIndex = ~0;
145         request.mask =
146             new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
147                 (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00};
148         return request;
149     }
150
151     @Test
152     public void testCreate() throws Exception {
153         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
154         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
155
156         whenClassifyAddDelTableThenSuccess();
157
158         customizer.writeCurrentAttributes(id, classifyTable, writeContext);
159
160         verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
161         verify(mappingContext)
162             .put(eq(getMappingIid(TABLE_NAME, "test-instance")), eq(getMapping(TABLE_NAME, TABLE_INDEX).get()));
163     }
164
165     @Test
166     public void testCreateFailed() throws Exception {
167         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
168         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
169
170         whenClassifyAddDelTableThenFailure();
171
172         try {
173             customizer.writeCurrentAttributes(id, classifyTable, writeContext);
174         } catch (WriteFailedException.CreateFailedException e) {
175             assertTrue(e.getCause() instanceof VppBaseCallException);
176             verifyClassifyAddDelTableAddWasInvoked(generateClassifyAddDelTable((byte) 1, TABLE_INDEX));
177             verify(mappingContext, times(0)).put(
178                 eq(getMappingIid(TABLE_NAME, "test-instance")),
179                 eq(getMapping(TABLE_NAME, TABLE_INDEX).get()));
180             return;
181         }
182         fail("WriteFailedException.CreateFailedException was expected");
183     }
184
185     @Test
186     public void testDelete() throws Exception {
187         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
188         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
189
190         final Optional<Mapping> ifcMapping = getMapping(TABLE_NAME, TABLE_INDEX);
191         doReturn(ifcMapping).when(mappingContext).read(any());
192
193         whenClassifyAddDelTableThenSuccess();
194
195         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
196
197         verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
198     }
199
200     @Test
201     public void testDeleteFailed() throws Exception {
202         final ClassifyTable classifyTable = generateClassifyTable(TABLE_NAME);
203         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
204
205         final Optional<Mapping> ifcMapping = getMapping(TABLE_NAME, TABLE_INDEX);
206         doReturn(ifcMapping).when(mappingContext).read(any());
207
208         whenClassifyAddDelTableThenFailure();
209
210         try {
211             customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
212         } catch (WriteFailedException.DeleteFailedException e) {
213             assertTrue(e.getCause() instanceof VppBaseCallException);
214             verifyClassifyAddDelTableDeleteWasInvoked(generateClassifyAddDelTable((byte) 0, TABLE_INDEX));
215             return;
216         }
217         fail("WriteFailedException.DeleteFailedException was expected");
218
219         customizer.deleteCurrentAttributes(id, classifyTable, writeContext);
220     }
221
222     @Test(expected = UnsupportedOperationException.class)
223     public void testUpdate() throws Exception {
224         final ClassifyTable classifyTableBefore = generateClassifyTable(TABLE_NAME);
225         final InstanceIdentifier<ClassifyTable> id = getClassifyTableId(TABLE_NAME);
226         customizer.updateCurrentAttributes(id, classifyTableBefore, new ClassifyTableBuilder().build(), writeContext);
227     }
228 }