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;
20 import org.junit.AfterClass;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.mdsal.binding.model.api.Enumeration;
26 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
27 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
28 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
29 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
30 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
31 import org.opendaylight.mdsal.binding.model.api.Type;
32 import org.opendaylight.mdsal.binding.model.ri.Types;
33 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
34 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
37 * General test suite revolving around {@link DefaultBindingGenerator}. This class holds tests originally aimed at
38 * specific implementation methods, but now they really are all about integration testing.
40 * @author Lukas Sedlak
41 * @author Robert Varga
43 @RunWith(MockitoJUnitRunner.class)
44 public class DefaultBindingGeneratorTest {
45 public static final String BASE_YANG_TYPES =
46 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.base.yang.types.rev140914";
47 public static final String TEST_TYPE_PROVIDER =
48 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.type.provider.model.rev140912";
49 public static final String TEST_TYPE_PROVIDER_B =
50 "org.opendaylight.yang.gen.v1.urn.opendaylight.org.test.type.provider.b.model.rev140915";
51 public static final JavaTypeName CONSTRUCTION_TYPE_TEST =
52 JavaTypeName.create(TEST_TYPE_PROVIDER, "ConstructionTypeTest");
53 public static final JavaTypeName TEST_TYPE_PROVIDER_B_DATA =
54 JavaTypeName.create(TEST_TYPE_PROVIDER_B, "TestTypeProviderBData");
55 public static final JavaTypeName TEST_TYPE_PROVIDER_FOO =
56 JavaTypeName.create(TEST_TYPE_PROVIDER, "Foo");
58 public static EffectiveModelContext SCHEMA_CONTEXT;
59 public static List<GeneratedType> TYPES;
62 public static void beforeClass() {
63 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResources(DefaultBindingGeneratorTest.class,
64 "/base-yang-types.yang", "/test-type-provider-b.yang", "/test-type-provider.yang");
65 TYPES = DefaultBindingGenerator.generateFor(SCHEMA_CONTEXT);
69 public static void afterClass() {
70 SCHEMA_CONTEXT = null;
75 public void javaTypeForSchemaDefinitionLeafrefToEnumTypeTest() {
76 final var bData = assertGeneratedType(TEST_TYPE_PROVIDER_B_DATA);
77 final var bDataMethods = bData.getMethodDefinitions();
78 assertEquals(8, bDataMethods.size());
80 final var bEnumType = assertGeneratedMethod(bDataMethods, "getEnum").getReturnType();
81 assertThat(bEnumType, instanceOf(Enumeration.class));
82 assertEquals(TEST_TYPE_PROVIDER + ".Foo.ResolveDirectUseOfEnum", bEnumType.getFullyQualifiedName());
84 final var bEnumsType = assertGeneratedMethod(bDataMethods, "getEnums").getReturnType();
86 assertThat(bEnumsType, instanceOf(ParameterizedType.class));
87 final var enumsType = (ParameterizedType) bEnumsType;
89 assertEquals(Types.typeForClass(List.class), enumsType.getRawType());
90 final var enumsTypeArgs = enumsType.getActualTypeArguments();
91 assertEquals(1, enumsTypeArgs.length);
92 assertEquals(TEST_TYPE_PROVIDER + ".Foo.ListOfEnums", enumsTypeArgs[0].getFullyQualifiedName());
96 public void generatedTypeForExtendedDefinitionTypeWithIdentityrefBaseTypeTest() {
97 assertEquals(Types.parameterizedTypeFor(Types.CLASS, Type.of(JavaTypeName.create(TEST_TYPE_PROVIDER, "Aes"))),
98 assertGeneratedMethod(CONSTRUCTION_TYPE_TEST, "getAesIdentityrefType").getReturnType());
102 public void generatedTypeForExtendedDefinitionTypeWithLeafrefBaseTypeTest() {
103 final var type = assertGeneratedMethod(CONSTRUCTION_TYPE_TEST, "getBarId").getReturnType();
104 assertThat(type, instanceOf(GeneratedTransferObject.class));
105 final var gto = (GeneratedTransferObject) type;
106 assertEquals(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16"), gto.getIdentifier());
110 public void generatedTypeForExtendedDefinitionTypeWithInnerExtendedTypeTest() {
111 assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ExtendedYangInt8"));
115 public void generatedTypeForExtendedDefinitionTypeTest() {
116 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBoolean"));
117 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangEmpty"));
118 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8"));
119 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8Restricted"));
120 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16"));
121 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt32"));
122 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt64"));
123 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangString"));
124 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangDecimal64"));
125 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint8"));
126 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint16"));
127 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint32"));
128 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUint64"));
129 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangUnion"));
130 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBinary"));
131 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInstanceIdentifier"));
132 assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangBits"));
133 assertEnumeration(JavaTypeName.create(BASE_YANG_TYPES, "YangEnumeration"));
137 public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionTypesTest() {
138 final var gto = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexUnion"));
139 assertEquals(3, gto.getProperties().size());
140 assertEquals(List.of(), gto.getEnumerations());
141 final var enclosed = gto.getEnclosedTypes();
142 assertEquals(1, enclosed.size());
144 final var union1 = enclosed.get(0);
145 assertThat(union1, instanceOf(GeneratedTransferObject.class));
146 assertEquals(TEST_TYPE_PROVIDER + ".ComplexUnion.ComplexUnion$1", union1.getFullyQualifiedName());
147 assertEquals(1, union1.getProperties().size());
148 assertEquals(List.of(), union1.getEnclosedTypes());
150 final var enums = union1.getEnumerations();
151 assertEquals(1, enums.size());
152 assertEquals(TEST_TYPE_PROVIDER + ".ComplexUnion.ComplexUnion$1.Enumeration",
153 enums.get(0).getFullyQualifiedName());
157 public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionAndSimpleTypeTest() {
158 final var gto = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexStringIntUnion"));
159 assertEquals(2, gto.getProperties().size());
160 assertEquals(List.of(), gto.getEnumerations());
161 assertEquals(List.of(), gto.getEnclosedTypes());
165 public void javaTypeForSchemaDefinitionForExtUnionWithSimpleTypesTest() {
166 final var type = assertGeneratedMethod(
167 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getSimpleIntTypesUnion").getReturnType();
168 assertThat(type, instanceOf(GeneratedTransferObject.class));
169 assertEquals(JavaTypeName.create(BASE_YANG_TYPES, "YangUnion"), type.getIdentifier());
173 public void javaTypeForSchemaDefinitionForExtUnionWithInnerUnionAndSimpleTypeTest() {
174 final var type = assertGeneratedMethod(
175 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getComplexStringIntUnion").getReturnType();
176 assertThat(type, instanceOf(GeneratedTransferObject.class));
177 assertEquals(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexStringIntUnion"), type.getIdentifier());
181 public void javaTypeForSchemaDefinitionForExtComplexUnionWithInnerUnionTypesTest() {
182 final var type = assertGeneratedMethod(
183 JavaTypeName.create(TEST_TYPE_PROVIDER, "UseOfUnions"), "getComplexUnion").getReturnType();
184 assertThat(type, instanceOf(GeneratedTransferObject.class));
185 assertEquals(JavaTypeName.create(TEST_TYPE_PROVIDER, "ComplexUnion"), type.getIdentifier());
189 public void javaTypeForSchemaDefinitionIdentityrefExtTypeTest() {
190 assertEquals(Types.parameterizedTypeFor(Types.CLASS,
191 Types.wildcardTypeFor(JavaTypeName.create(TEST_TYPE_PROVIDER, "CryptoAlg"))),
192 assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getCrypto").getReturnType());
196 public void javaTypeForSchemaDefinitionEmptyStringPatternTypeTest() {
197 final var restrictions = assertGTO(JavaTypeName.create(TEST_TYPE_PROVIDER, "EmptyPatternString"))
199 final var patterns = restrictions.getPatternConstraints();
200 assertEquals(1, patterns.size());
201 final var pattern = patterns.get(0);
202 assertEquals("", pattern.getRegularExpressionString());
203 assertEquals("^(?:)$", pattern.getJavaPatternString());
207 public void testUnresolvedLeafref() {
208 assertSame(Types.objectType(),
209 assertGeneratedMethod(JavaTypeName.create(TEST_TYPE_PROVIDER_B, "Grp"), "getUnresolvableLeafref")
214 public void javaTypeForSchemaDefinitionInvalidLeafrefPathTest() {
215 final var ctx = YangParserTestUtils.parseYangResource("/unresolvable-leafref.yang");
216 final var ex = assertThrows(IllegalArgumentException.class, () -> DefaultBindingGenerator.generateFor(ctx));
217 assertEquals("Failed to find leafref target /somewhere/i/belong", ex.getMessage());
218 final var cause = ex.getCause();
219 assertThat(cause, instanceOf(IllegalArgumentException.class));
220 assertEquals("Data tree child (foo)somewhere not present in module (foo)unresolvable-leafref",
225 public void javaTypeForSchemaDefinitionConditionalLeafrefTest() {
226 // Note: previous incarnation did not resolve this, as the expression (pointed to a list)
227 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16")),
228 assertGeneratedMethod(TEST_TYPE_PROVIDER_B_DATA, "getConditionalLeafref").getReturnType());
232 public void javaTypeForSchemaDefinitionLeafrefExtTypeTest() {
233 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8")),
234 assertGeneratedMethod(JavaTypeName.create(TEST_TYPE_PROVIDER, "Bar"), "getLeafrefValue").getReturnType());
235 assertSame(assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt16")),
236 assertGeneratedMethod(TEST_TYPE_PROVIDER_B_DATA, "getId").getReturnType());
240 public void javaTypeForSchemaDefinitionEnumExtTypeTest() {
241 final var expected = assertGeneratedType(JavaTypeName.create(BASE_YANG_TYPES, "YangEnumeration"));
242 assertThat(expected, instanceOf(Enumeration.class));
243 var enumValues = ((Enumeration) expected).getValues();
244 assertEquals(2, enumValues.size());
245 assertEquals("a", enumValues.get(0).getName());
246 assertEquals("A", enumValues.get(0).getMappedName());
247 assertEquals("b", enumValues.get(1).getName());
248 assertEquals("B", enumValues.get(1).getMappedName());
250 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getResolveEnumLeaf").getReturnType());
252 // Note: this part of the test contained invalid assertion that the return would be java.lang.Enum
253 final var type = assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getResolveDirectUseOfEnum").getReturnType();
254 assertEquals(TEST_TYPE_PROVIDER_FOO.createEnclosed("ResolveDirectUseOfEnum"), type.getIdentifier());
255 assertThat(expected, instanceOf(Enumeration.class));
256 enumValues = ((Enumeration) type).getValues();
257 assertEquals(3, enumValues.size());
258 assertEquals("x", enumValues.get(0).getName());
259 assertEquals("X", enumValues.get(0).getMappedName());
260 assertEquals("y", enumValues.get(1).getName());
261 assertEquals("Y", enumValues.get(1).getMappedName());
262 assertEquals("z", enumValues.get(2).getName());
263 assertEquals("Z", enumValues.get(2).getMappedName());
267 public void javaTypeForSchemaDefinitionRestrictedExtTypeTest() {
268 final var expected = assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8Restricted"));
269 assertEquals(1, expected.getProperties().size());
270 final var rangeConstraints = expected.getRestrictions().getRangeConstraint();
271 assertTrue(rangeConstraints.isPresent());
272 final var it = rangeConstraints.orElseThrow().getAllowedRanges().asRanges().iterator();
273 assertTrue(it.hasNext());
274 final var constraint = it.next();
275 assertEquals((byte) 1, constraint.lowerEndpoint());
276 assertEquals((byte) 100, constraint.upperEndpoint());
277 assertFalse(it.hasNext());
279 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getRestrictedInt8Type").getReturnType());
283 public void javaTypeForSchemaDefinitionExtTypeTest() {
284 final var expected = assertGTO(JavaTypeName.create(BASE_YANG_TYPES, "YangInt8"));
285 assertEquals(1, expected.getProperties().size());
287 assertSame(expected, assertGeneratedMethod(TEST_TYPE_PROVIDER_FOO, "getYangInt8Type").getReturnType());
290 private static MethodSignature assertGeneratedMethod(final JavaTypeName typeName, final String methodName) {
291 return assertGeneratedMethod(assertGeneratedType(typeName).getMethodDefinitions(), methodName);
294 private static MethodSignature assertGeneratedMethod(final List<MethodSignature> methods, final String name) {
295 return methods.stream().filter(method -> name.equals(method.getName()))
297 .orElseThrow(() -> new AssertionError("Method " + name + " not present"));
300 private static GeneratedType assertGeneratedType(final JavaTypeName name) {
301 return TYPES.stream()
302 .filter(type -> name.equals(type.getIdentifier()))
304 .orElseThrow(() -> new AssertionError("Generated type " + name + " not present"));
307 private static Enumeration assertEnumeration(final JavaTypeName name) {
308 final var type = assertGeneratedType(name);
309 assertThat(type, instanceOf(Enumeration.class));
310 return (Enumeration) type;
313 private static GeneratedTransferObject assertGTO(final JavaTypeName name) {
314 final var type = assertGeneratedType(name);
315 assertThat(type, instanceOf(GeneratedTransferObject.class));
316 return (GeneratedTransferObject) type;