2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
3 * Copyright (c) 2021 PANTHEON.tech, s.r.o.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.mdsal.binding.generator.impl;
11 import static org.hamcrest.CoreMatchers.instanceOf;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertSame;
16 import static org.junit.Assert.assertThrows;
17 import static org.junit.Assert.assertTrue;
19 import java.util.List;
21 import org.junit.AfterClass;
22 import org.junit.BeforeClass;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.junit.MockitoJUnitRunner;
26 import org.opendaylight.mdsal.binding.model.api.Enumeration;
27 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
28 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
29 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
30 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
31 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
32 import org.opendaylight.mdsal.binding.model.api.Type;
33 import org.opendaylight.mdsal.binding.model.ri.Types;
34 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
35 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
38 * General test suite revolving around {@link DefaultBindingGenerator}. This class holds tests originally aimed at
39 * specific implementation methods, but now they really are all about integration testing.
41 * @author Lukas Sedlak
42 * @author Robert Varga
44 @RunWith(MockitoJUnitRunner.class)
45 public class DefaultBindingGeneratorTest {
46 public static final String BASE_YANG_TYPES =
47 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.base.yang.types.rev140914";
48 public static final String TEST_TYPE_PROVIDER =
49 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.type.provider.model.rev140912";
50 public static final String TEST_TYPE_PROVIDER_B =
51 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.type.provider.b.model.rev140915";
52 public static final JavaTypeName CONSTRUCTION_TYPE_TEST =
53 JavaTypeName.create(TEST_TYPE_PROVIDER, "ConstructionTypeTest");
54 public static final JavaTypeName TEST_TYPE_PROVIDER_B_DATA =
55 JavaTypeName.create(TEST_TYPE_PROVIDER_B, "TestTypeProviderBData");
56 public static final JavaTypeName TEST_TYPE_PROVIDER_FOO =
57 JavaTypeName.create(TEST_TYPE_PROVIDER, "Foo");
59 public static EffectiveModelContext SCHEMA_CONTEXT;
60 public static List<GeneratedType> TYPES;
63 public static void beforeClass() {
64 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResources(DefaultBindingGeneratorTest.class,
65 "/base-yang-types.yang", "/test-type-provider-b.yang", "/test-type-provider.yang");
66 TYPES = DefaultBindingGenerator.generateFor(SCHEMA_CONTEXT);
70 public static void afterClass() {
71 SCHEMA_CONTEXT = null;
76 public void javaTypeForSchemaDefinitionLeafrefToEnumTypeTest() {
77 final var bData = assertGeneratedType(TEST_TYPE_PROVIDER_B_DATA);
78 final var bDataMethods = bData.getMethodDefinitions();
79 assertEquals(8, bDataMethods.size());
81 final var bEnumType = assertGeneratedMethod(bDataMethods, "getEnum").getReturnType();
82 assertThat(bEnumType, instanceOf(Enumeration.class));
83 assertEquals(TEST_TYPE_PROVIDER + ".Foo.ResolveDirectUseOfEnum", bEnumType.getFullyQualifiedName());
85 final var bEnumsType = assertGeneratedMethod(bDataMethods, "getEnums").getReturnType();
87 assertThat(bEnumsType, instanceOf(ParameterizedType.class));
88 final var enumsType = (ParameterizedType) bEnumsType;
90 assertEquals(Types.typeForClass(Set.class), enumsType.getRawType());
91 final var enumsTypeArgs = enumsType.getActualTypeArguments();
92 assertEquals(1, enumsTypeArgs.length);
93 assertEquals(TEST_TYPE_PROVIDER + ".Foo.ListOfEnums", enumsTypeArgs[0].getFullyQualifiedName());
97 public void generatedTypeForExtendedDefinitionTypeWithIdentityrefBaseTypeTest() {
98 assertEquals(Types.parameterizedTypeFor(Types.CLASS, Type.of(JavaTypeName.create(TEST_TYPE_PROVIDER, "Aes"))),
99 assertGeneratedMethod(CONSTRUCTION_TYPE_TEST, "getAesIdentityrefType").getReturnType());
103 public void generatedTypeForExtendedDefinitionTypeWithLeafrefBaseTypeTest() {
104 final var type = assertGeneratedMethod(CONSTRUCTION_TYPE_TEST, "getBarId").getReturnType();
105 assertThat(type, instanceOf(GeneratedTransferObject.class));
106 final var gto = (GeneratedTransferObject) type;
107 assertEquals(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16"), gto.getIdentifier());
111 public void generatedTypeForExtendedDefinitionTypeWithInnerExtendedTypeTest() {
112 assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ExtendedYangInt8"));
116 public void generatedTypeForExtendedDefinitionTypeTest() {
117 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBoolean"));
118 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangEmpty"));
119 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8"));
120 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8Restricted"));
121 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16"));
122 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt32"));
123 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt64"));
124 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangString"));
125 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangDecimal64"));
126 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint8"));
127 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint16"));
128 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint32"));
129 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint64"));
130 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUnion"));
131 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBinary"));
132 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInstanceIdentifier"));
133 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBits"));
134 assertEnumeration(JavaTypeName.create(BASE_YANG_TYPES, "YangEnumeration"));
138 public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionTypesTest() {
139 final var gto = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexUnion"));
140 assertEquals(3, gto.getProperties().size());
141 assertEquals(List.of(), gto.getEnumerations());
142 final var enclosed = gto.getEnclosedTypes();
143 assertEquals(1, enclosed.size());
145 final var union1 = enclosed.get(0);
146 assertThat(union1, instanceOf(GeneratedTransferObject.class));
147 assertEquals(TEST_TYPE_PROVIDER + ".ComplexUnion.ComplexUnion$1", union1.getFullyQualifiedName());
148 assertEquals(1, union1.getProperties().size());
149 assertEquals(List.of(), union1.getEnclosedTypes());
151 final var enums = union1.getEnumerations();
152 assertEquals(1, enums.size());
153 assertEquals(TEST_TYPE_PROVIDER + ".ComplexUnion.ComplexUnion$1.Enumeration",
154 enums.get(0).getFullyQualifiedName());
158 public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionAndSimpleTypeTest() {
159 final var gto = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexStringIntUnion"));
160 assertEquals(2, gto.getProperties().size());
161 assertEquals(List.of(), gto.getEnumerations());
162 assertEquals(List.of(), gto.getEnclosedTypes());
166 public void javaTypeForSchemaDefinitionForExtUnionWithSimpleTypesTest() {
167 final var type = assertGeneratedMethod(
168 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getSimpleIntTypesUnion").getReturnType();
169 assertThat(type, instanceOf(GeneratedTransferObject.class));
170 assertEquals(JavaTypeName.create(BASE_YANG_TYPES, "YangUnion"), type.getIdentifier());
174 public void javaTypeForSchemaDefinitionForExtUnionWithInnerUnionAndSimpleTypeTest() {
175 final var type = assertGeneratedMethod(
176 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getComplexStringIntUnion").getReturnType();
177 assertThat(type, instanceOf(GeneratedTransferObject.class));
178 assertEquals(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexStringIntUnion"), type.getIdentifier());
182 public void javaTypeForSchemaDefinitionForExtComplexUnionWithInnerUnionTypesTest() {
183 final var type = assertGeneratedMethod(
184 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getComplexUnion").getReturnType();
185 assertThat(type, instanceOf(GeneratedTransferObject.class));
186 assertEquals(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexUnion"), type.getIdentifier());
190 public void javaTypeForSchemaDefinitionIdentityrefExtTypeTest() {
191 assertEquals(Types.parameterizedTypeFor(Types.CLASS,
192 Types.wildcardTypeFor(JavaTypeName.create(TEST_TYPE_PROVIDER, "CryptoAlg"))),
193 assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getCrypto").getReturnType());
197 public void javaTypeForSchemaDefinitionEmptyStringPatternTypeTest() {
198 final var restrictions = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "EmptyPatternString"))
200 final var patterns = restrictions.getPatternConstraints();
201 assertEquals(1, patterns.size());
202 final var pattern = patterns.get(0);
203 assertEquals("", pattern.getRegularExpressionString());
204 assertEquals("^(?:)$", pattern.getJavaPatternString());
208 public void testUnresolvedLeafref() {
209 assertSame(Types.objectType(),
210 assertGeneratedMethod(JavaTypeName.create(TEST_TYPE_PROVIDER_B, "Grp"), "getUnresolvableLeafref")
215 public void javaTypeForSchemaDefinitionInvalidLeafrefPathTest() {
216 final var ctx = YangParserTestUtils.parseYangResource("/unresolvable-leafref.yang");
217 final var ex = assertThrows(IllegalArgumentException.class, () -> DefaultBindingGenerator.generateFor(ctx));
218 assertEquals("Failed to find leafref target /somewhere/i/belong", ex.getMessage());
219 final var cause = ex.getCause();
220 assertThat(cause, instanceOf(IllegalArgumentException.class));
221 assertEquals("Data tree child (foo)somewhere not present in module (foo)unresolvable-leafref",
226 public void javaTypeForSchemaDefinitionConditionalLeafrefTest() {
227 // Note: previous incarnation did not resolve this, as the expression (pointed to a list)
228 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16")),
229 assertGeneratedMethod(TEST_TYPE_PROVIDER_B_DATA, "getConditionalLeafref").getReturnType());
233 public void javaTypeForSchemaDefinitionLeafrefExtTypeTest() {
234 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8")),
235 assertGeneratedMethod(JavaTypeName.create(TEST_TYPE_PROVIDER, "Bar"), "getLeafrefValue").getReturnType());
236 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16")),
237 assertGeneratedMethod(TEST_TYPE_PROVIDER_B_DATA, "getId").getReturnType());
241 public void javaTypeForSchemaDefinitionEnumExtTypeTest() {
242 final var expected = assertGeneratedType(JavaTypeName.create(BASE_YANG_TYPES, "YangEnumeration"));
243 assertThat(expected, instanceOf(Enumeration.class));
244 var enumValues = ((Enumeration) expected).getValues();
245 assertEquals(2, enumValues.size());
246 assertEquals("a", enumValues.get(0).getName());
247 assertEquals("A", enumValues.get(0).getMappedName());
248 assertEquals("b", enumValues.get(1).getName());
249 assertEquals("B", enumValues.get(1).getMappedName());
251 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getResolveEnumLeaf").getReturnType());
253 // Note: this part of the test contained invalid assertion that the return would be java.lang.Enum
254 final var type = assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getResolveDirectUseOfEnum").getReturnType();
255 assertEquals(TEST_TYPE_PROVIDER_FOO.createEnclosed("ResolveDirectUseOfEnum"), type.getIdentifier());
256 assertThat(expected, instanceOf(Enumeration.class));
257 enumValues = ((Enumeration) type).getValues();
258 assertEquals(3, enumValues.size());
259 assertEquals("x", enumValues.get(0).getName());
260 assertEquals("X", enumValues.get(0).getMappedName());
261 assertEquals("y", enumValues.get(1).getName());
262 assertEquals("Y", enumValues.get(1).getMappedName());
263 assertEquals("z", enumValues.get(2).getName());
264 assertEquals("Z", enumValues.get(2).getMappedName());
268 public void javaTypeForSchemaDefinitionRestrictedExtTypeTest() {
269 final var expected = assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8Restricted"));
270 assertEquals(1, expected.getProperties().size());
271 final var rangeConstraints = expected.getRestrictions().getRangeConstraint();
272 assertTrue(rangeConstraints.isPresent());
273 final var it = rangeConstraints.orElseThrow().getAllowedRanges().asRanges().iterator();
274 assertTrue(it.hasNext());
275 final var constraint = it.next();
276 assertEquals((byte) 1, constraint.lowerEndpoint());
277 assertEquals((byte) 100, constraint.upperEndpoint());
278 assertFalse(it.hasNext());
280 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getRestrictedInt8Type").getReturnType());
284 public void javaTypeForSchemaDefinitionExtTypeTest() {
285 final var expected = assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8"));
286 assertEquals(1, expected.getProperties().size());
288 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getYangInt8Type").getReturnType());
291 private static MethodSignature assertGeneratedMethod(final JavaTypeName typeName, final String methodName) {
292 return assertGeneratedMethod(assertGeneratedType(typeName).getMethodDefinitions(), methodName);
295 private static MethodSignature assertGeneratedMethod(final List<MethodSignature> methods, final String name) {
296 return methods.stream().filter(method -> name.equals(method.getName()))
298 .orElseThrow(() -> new AssertionError("Method " + name + " not present"));
301 private static GeneratedType assertGeneratedType(final JavaTypeName name) {
302 return TYPES.stream()
303 .filter(type -> name.equals(type.getIdentifier()))
305 .orElseThrow(() -> new AssertionError("Generated type " + name + " not present"));
308 private static Enumeration assertEnumeration(final JavaTypeName name) {
309 final var type = assertGeneratedType(name);
310 assertThat(type, instanceOf(Enumeration.class));
311 return (Enumeration) type;
314 private static GeneratedTransferObject assertGTO(final JavaTypeName name) {
315 final var type = assertGeneratedType(name);
316 assertThat(type, instanceOf(GeneratedTransferObject.class));
317 return (GeneratedTransferObject) type;