JavaIdentifierNormalizer ThreadSafe/Memory leak fix
[mdsal.git] / binding2 / mdsal-binding2-generator-impl / src / test / java / org / opendaylight / mdsal / binding / javav2 / generator / impl / RpcActionGenHelperTest.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.javav2.generator.impl;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.when;
16
17 import com.google.common.base.Optional;
18 import java.lang.reflect.Constructor;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import org.junit.Ignore;
30 import org.junit.Test;
31 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
32 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
33 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
34 import org.opendaylight.yangtools.yang.common.QName;
35 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
36 import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.Module;
41 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
42 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
43 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
44 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
45 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
46
47 public class RpcActionGenHelperTest {
48
49     @SuppressWarnings("unchecked")
50     @Test(expected = UnsupportedOperationException.class)
51     public void constructorTest() throws Throwable {
52         final Constructor<RpcActionGenHelper> constructor =
53                 (Constructor<RpcActionGenHelper>) RpcActionGenHelper.class.getDeclaredConstructors()[0];
54         constructor.setAccessible(true);
55         final Object[] objs = {};
56         try {
57             constructor.newInstance(objs);
58         } catch (final Exception e) {
59             throw e.getCause();
60         }
61     }
62
63     @SuppressWarnings({ "rawtypes", "unchecked" })
64     @Test
65     public void getRoutingContextAbsentTest() throws Exception {
66         final Class[] parameterTypes = { DataSchemaNode.class };
67         final Method generate = RpcActionGenHelper.class.getDeclaredMethod("getRoutingContext", parameterTypes);
68         assertNotNull(generate);
69         generate.setAccessible(true);
70         final DataSchemaNode dataSchemaNode = mock(DataSchemaNode.class);
71         final List<UnknownSchemaNode> unknownSchemaNodes = new ArrayList<>();
72         when(dataSchemaNode.getUnknownSchemaNodes()).thenReturn(unknownSchemaNodes);
73
74         final Object[] args = { dataSchemaNode };
75         final Optional<QName> result = (Optional<QName>) generate.invoke(RpcActionGenHelper.class, args);
76         assertNotNull(result);
77         assertTrue(!result.isPresent());
78     }
79
80     @SuppressWarnings({ "rawtypes", "unchecked" })
81     @Test
82     public void getRoutingContextTest() throws Exception {
83         final Class[] parameterTypes = { DataSchemaNode.class };
84         final Method generate = RpcActionGenHelper.class.getDeclaredMethod("getRoutingContext", parameterTypes);
85         assertNotNull(generate);
86         generate.setAccessible(true);
87
88         final DataSchemaNode dataSchemaNode = mock(DataSchemaNode.class);
89         final List<UnknownSchemaNode> unknownSchemaNodes = new ArrayList<>();
90         final Field contextRef = RpcActionGenHelper.class.getDeclaredField("CONTEXT_REFERENCE");
91         contextRef.setAccessible(true);
92         final QName nodeType = (QName) contextRef.get(RpcActionGenHelper.class);
93         final UnknownSchemaNode unknownSchemaNode = mock(UnknownSchemaNode.class);
94         when(unknownSchemaNode.getNodeType()).thenReturn(nodeType);
95         final QName qname = QName.create("test", "2017-05-04", "unknown");
96         when(unknownSchemaNode.getQName()).thenReturn(qname);
97         unknownSchemaNodes.add(unknownSchemaNode);
98         when(dataSchemaNode.getUnknownSchemaNodes()).thenReturn(unknownSchemaNodes);
99
100         final Object[] args = { dataSchemaNode };
101         final Optional<QName> result = (Optional<QName>) generate.invoke(RpcActionGenHelper.class, args);
102         assertNotNull(result);
103         assertTrue(result.isPresent());
104         assertEquals(qname, result.get());
105     }
106
107     @Ignore
108     @Test
109     public void actionMethodsToGenTypeContainerAsParentTest() throws Exception {
110         actionMethodsToGenType(ContainerSchemaNode.class, false);
111     }
112
113     @Ignore
114     @Test
115     public void actionMethodsToGenTypeListAsParentTest() throws Exception {
116         actionMethodsToGenType(ListSchemaNode.class, false);
117     }
118
119     @SuppressWarnings("rawtypes")
120     @Test
121     public void rpcMethodsToGenTypeNullRpcsTest() throws Exception {
122         final Class[] parameterTypes =
123                 { Module.class, Map.class, SchemaContext.class, boolean.class, Map.class, TypeProvider.class };
124         final Method generate = RpcActionGenHelper.class.getDeclaredMethod("rpcMethodsToGenType", parameterTypes);
125         assertNotNull(generate);
126         generate.setAccessible(true);
127
128         final QName rpcQName = QName.create("test.rpc", "2017-05-04", "rpc-test");
129
130         final Module module = mock(Module.class);
131         when(module.getName()).thenReturn("module-name");
132         when(module.getRevision()).thenReturn(rpcQName.getRevision());
133         when(module.getNamespace()).thenReturn(rpcQName.getNamespace());
134         when(module.getRpcs()).thenReturn(null);
135
136         final Map<Module, ModuleContext> genCtx = new HashMap<>();
137         final SchemaContext schemaContext = mock(SchemaContext.class);
138         final boolean verboseClassComments = false;
139         final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders = new HashMap<>();
140         final TypeProvider typeProvider = mock(TypeProvider.class);
141
142         final Object[] args = { module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider };
143
144         try {
145             generate.invoke(RpcActionGenHelper.class, args);
146             fail();
147         } catch (final Exception e) {
148             assertNotNull(e);
149             assertTrue(e instanceof InvocationTargetException);
150             final Throwable cause = e.getCause();
151             assertNotNull(cause);
152             assertTrue(cause instanceof IllegalStateException);
153         }
154     }
155
156     @SuppressWarnings({ "rawtypes", "unchecked" })
157     @Test
158     public void rpcMethodsToGenTypeEmptyRpcsTest() throws Exception {
159         final Class[] parameterTypes =
160                 { Module.class, Map.class, SchemaContext.class, boolean.class, Map.class, TypeProvider.class };
161         final Method generate = RpcActionGenHelper.class.getDeclaredMethod("rpcMethodsToGenType", parameterTypes);
162         assertNotNull(generate);
163         generate.setAccessible(true);
164
165         final QName rpcQName = QName.create("test.rpc", "2017-05-04", "rpc-test");
166
167         final Module module = mock(Module.class);
168         when(module.getName()).thenReturn("module-name");
169         when(module.getRevision()).thenReturn(rpcQName.getRevision());
170         when(module.getNamespace()).thenReturn(rpcQName.getNamespace());
171         final Set<RpcDefinition> rpcs = new HashSet<>();
172         when(module.getRpcs()).thenReturn(rpcs);
173
174         final Map<Module, ModuleContext> genCtx = new HashMap<>();
175         final SchemaContext schemaContext = mock(SchemaContext.class);
176         final boolean verboseClassComments = false;
177         final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders = new HashMap<>();
178         final TypeProvider typeProvider = mock(TypeProvider.class);
179
180         final Object[] args = { module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider };
181         final Map<Module, ModuleContext> result =
182                 (Map<Module, ModuleContext>) generate.invoke(RpcActionGenHelper.class, args);
183         assertNotNull(result);
184     }
185
186     @Test
187     public void rpcMethodsToGenTypeRoutedRpcTest() throws Exception {
188         actionMethodsToGenType(ContainerSchemaNode.class, true);
189     }
190
191     @SuppressWarnings({ "rawtypes", "unchecked" })
192     @Test
193     public void rpcMethodsToGenTypeRpcTest() throws Exception {
194         final Class[] parameterTypes =
195                 { Module.class, Map.class, SchemaContext.class, boolean.class, Map.class, TypeProvider.class };
196         final Method generate = RpcActionGenHelper.class.getDeclaredMethod("rpcMethodsToGenType", parameterTypes);
197         assertNotNull(generate);
198         generate.setAccessible(true);
199
200         final QName rpcQName = QName.create("test.rpc", "2017-05-04", "rpc-test");
201
202         final ContainerSchemaNode rpcParent = mock(ContainerSchemaNode.class);
203         final QName rpcParentQName = QName.create(rpcQName, "rpc-parent");
204         when(rpcParent.getQName()).thenReturn(rpcParentQName);
205
206         final Module module = mock(Module.class);
207         when(module.getName()).thenReturn("module-name");
208         when(module.getRevision()).thenReturn(rpcQName.getRevision());
209         when(module.getNamespace()).thenReturn(rpcQName.getNamespace());
210         final Set<RpcDefinition> rpcs = new HashSet<>();
211         final RpcDefinition rpcDefinition = mock(RpcDefinition.class);
212         final SchemaPath rpcPath = SchemaPath.create(true, rpcParentQName, rpcQName);
213         when(rpcDefinition.getPath()).thenReturn(rpcPath);
214         when(rpcDefinition.getQName()).thenReturn(rpcQName);
215         when(module.getDataChildByName(rpcParentQName)).thenReturn(rpcParent);
216         rpcs.add(rpcDefinition);
217         when(module.getRpcs()).thenReturn(rpcs);
218
219         final ContainerSchemaNode input = mock(ContainerSchemaNode.class);
220         final QName qnameInput = QName.create(rpcQName, "rpc-input");
221         final SchemaPath inputSchemaPath = SchemaPath.create(true, rpcQName, qnameInput);
222         when(input.getQName()).thenReturn(qnameInput);
223         when(input.getPath()).thenReturn(inputSchemaPath);
224         when(rpcDefinition.getInput()).thenReturn(input);
225
226         final ContainerSchemaNode output = mock(ContainerSchemaNode.class);
227         final QName qnameOutput = QName.create(rpcQName, "rpc-output");
228         final SchemaPath outputSchemaPath = SchemaPath.create(true, rpcQName, qnameOutput);
229         when(output.getQName()).thenReturn(qnameOutput);
230         when(output.getPath()).thenReturn(outputSchemaPath);
231         when(rpcDefinition.getOutput()).thenReturn(output);
232
233         final Map<Module, ModuleContext> genCtx = new HashMap<>();
234         final ModuleContext moduleContext = new ModuleContext();
235         genCtx.put(module, moduleContext);
236
237         final SchemaContext schemaContext = mock(SchemaContext.class);
238         when(schemaContext.findModuleByNamespaceAndRevision(rpcQName.getNamespace(), rpcQName.getRevision()))
239                 .thenReturn(module);
240
241         final boolean verboseClassComments = false;
242         final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders = new HashMap<>();
243         final TypeProvider typeProvider = mock(TypeProvider.class);
244
245         final Object[] args = { module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider };
246         final Map<Module, ModuleContext> result =
247                 (Map<Module, ModuleContext>) generate.invoke(RpcActionGenHelper.class, args);
248         assertNotNull(result);
249     }
250
251     @SuppressWarnings({ "unchecked", "rawtypes" })
252     private <T extends ActionNodeContainer> void actionMethodsToGenType(final Class<T> clazz,
253             final boolean isRoutedRpc) throws Exception {
254         final Class[] parameterTypes =
255                 { Module.class, Map.class, SchemaContext.class, boolean.class, Map.class, TypeProvider.class };
256         Method generate;
257         if (isRoutedRpc) {
258             generate = RpcActionGenHelper.class.getDeclaredMethod("rpcMethodsToGenType", parameterTypes);
259         } else {
260             generate = RpcActionGenHelper.class.getDeclaredMethod("actionMethodsToGenType", parameterTypes);
261         }
262         assertNotNull(generate);
263         generate.setAccessible(true);
264
265         final QName actionQName = QName.create("test.action", "2017-05-04", "action-test");
266
267         final Module module = mock(Module.class);
268         when(module.getName()).thenReturn("module-name");
269         when(module.getRevision()).thenReturn(actionQName.getRevision());
270         when(module.getNamespace()).thenReturn(actionQName.getNamespace());
271
272         final Collection<DataSchemaNode> childNodes = new ArrayList<>();
273         final T actionNodeContainer = mock(clazz);
274         final QName actionParentQName = QName.create(actionQName, "action-parent");
275         final SchemaPath actionParentPath = SchemaPath.create(true, actionParentQName);
276         when(((SchemaNode) actionNodeContainer).getPath()).thenReturn(actionParentPath);
277         when(((SchemaNode) actionNodeContainer).getQName()).thenReturn(actionParentQName);
278         if (clazz == ListSchemaNode.class) {
279             final List<QName> keyQNames = new ArrayList<>();
280             keyQNames.add(QName.create(actionParentQName, "keyActions"));
281             when(((ListSchemaNode) actionNodeContainer).getKeyDefinition()).thenReturn(keyQNames);
282         }
283
284         final Set<ActionDefinition> actions = new HashSet<>();
285
286         final ActionDefinition actionDefinition = mock(ActionDefinition.class);
287         when(actionDefinition.getQName()).thenReturn(actionQName);
288         final SchemaPath actionPath = SchemaPath.create(true, actionQName);
289         when(actionDefinition.getPath()).thenReturn(actionPath);
290
291         final ContainerSchemaNode input = mock(ContainerSchemaNode.class);
292         final QName qnameInput = QName.create(actionQName, "action-input");
293         final SchemaPath inputSchemaPath = SchemaPath.create(true, actionQName, qnameInput);
294         when(input.getQName()).thenReturn(qnameInput);
295         when(input.getPath()).thenReturn(inputSchemaPath);
296         when(actionDefinition.getInput()).thenReturn(input);
297
298         final ContainerSchemaNode output = mock(ContainerSchemaNode.class);
299         final QName qnameOutput = QName.create(actionQName, "action-output");
300         final SchemaPath outputSchemaPath = SchemaPath.create(true, actionQName, qnameOutput);
301         when(output.getQName()).thenReturn(qnameOutput);
302         when(output.getPath()).thenReturn(outputSchemaPath);
303         when(actionDefinition.getOutput()).thenReturn(output);
304
305         actions.add(actionDefinition);
306         when(actionNodeContainer.getActions()).thenReturn(actions);
307         childNodes.add((DataSchemaNode) actionNodeContainer);
308         when(module.getChildNodes()).thenReturn(childNodes);
309
310         final Map<Module, ModuleContext> genCtx = new HashMap<>();
311         final ModuleContext moduleContext = new ModuleContext();
312         genCtx.put(module, moduleContext);
313
314         final SchemaContext schemaContext = mock(SchemaContext.class);
315         when(schemaContext.findModuleByNamespaceAndRevision(actionQName.getNamespace(), actionQName.getRevision()))
316                 .thenReturn(module);
317
318         final boolean verboseClassComments = false;
319         final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders = new HashMap<>();
320         final TypeProvider typeProvider = mock(TypeProvider.class);
321
322         if (isRoutedRpc) {
323             final Set<RpcDefinition> rpcs = new HashSet<>();
324             final RpcDefinition rpcDef = mock(RpcDefinition.class);
325             when(rpcDef.getPath()).thenReturn(outputSchemaPath);
326             when(rpcDef.getQName()).thenReturn(qnameOutput);
327             when(module.getDataChildByName(actionQName)).thenReturn((ContainerSchemaNode) actionNodeContainer);
328             final List<UnknownSchemaNode> unknownSchemaNodes = new ArrayList<>();
329             final UnknownSchemaNode unknownSchemaNode = mock(UnknownSchemaNode.class);
330             final Field contextRef = RpcActionGenHelper.class.getDeclaredField("CONTEXT_REFERENCE");
331             contextRef.setAccessible(true);
332             final QName nodeType = (QName) contextRef.get(RpcActionGenHelper.class);
333             when(unknownSchemaNode.getNodeType()).thenReturn(nodeType);
334             when(unknownSchemaNode.getQName()).thenReturn(nodeType);
335             unknownSchemaNodes.add(unknownSchemaNode);
336             when(((DataSchemaNode) actionNodeContainer).getUnknownSchemaNodes()).thenReturn(unknownSchemaNodes);
337             when(rpcDef.getInput()).thenReturn(input);
338             when(rpcDef.getOutput()).thenReturn(output);
339             rpcs.add(rpcDef);
340             when(module.getRpcs()).thenReturn(rpcs);
341         }
342
343         final Object[] args = { module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider };
344         final Map<Module, ModuleContext> result =
345                 (Map<Module, ModuleContext>) generate.invoke(RpcActionGenHelper.class, args);
346         assertNotNull(result);
347     }
348 }