2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.stmt;
10 import static org.hamcrest.CoreMatchers.startsWith;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertFalse;
14 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
15 import static org.junit.jupiter.api.Assertions.assertNotEquals;
16 import static org.junit.jupiter.api.Assertions.assertNotNull;
17 import static org.junit.jupiter.api.Assertions.assertSame;
18 import static org.junit.jupiter.api.Assertions.assertThrows;
19 import static org.junit.jupiter.api.Assertions.assertTrue;
20 import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
22 import com.google.common.collect.Iterables;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import org.junit.jupiter.api.Test;
27 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.Module;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
34 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
36 class EffectiveIdentityTest {
37 private static final StatementStreamSource IDENTITY_TEST = sourceForResource(
38 "/stmt-test/identity/identity-test.yang");
39 private static final StatementStreamSource CYCLIC_IDENTITY_TEST = sourceForResource(
40 "/stmt-test/identity/cyclic-identity-test.yang");
43 void cyclicDefineTest() {
44 final var reactor = RFC7950Reactors.defaultReactor().newBuild().addSources(CYCLIC_IDENTITY_TEST);
45 final var cause = assertThrows(SomeModifiersUnresolvedException.class, reactor::buildEffective).getCause();
46 assertInstanceOf(InferenceException.class, cause);
47 assertThat(cause.getMessage(), startsWith("Yang model processing phase STATEMENT_DEFINITION failed [at "));
49 // This is a bit complicated, as the order of exceptions may differ
50 final var causes = new ArrayList<Throwable>();
51 final var cause1 = cause.getCause();
55 causes.addAll(Arrays.asList(cause.getSuppressed()));
56 causes.sort(Comparator.comparing(Throwable::getMessage));
57 assertEquals(4, causes.size());
58 causes.forEach(throwable -> assertInstanceOf(InferenceException.class, throwable));
60 assertThat(causes.get(0).getMessage(),
61 startsWith("Unable to resolve identity (cyclic.identity.test)child-identity-1 and base identity "
62 + "(cyclic.identity.test)child-identity-2 [at "));
63 assertThat(causes.get(1).getMessage(),
64 startsWith("Unable to resolve identity (cyclic.identity.test)child-identity-2 and base identity "
65 + "(cyclic.identity.test)child-identity-3 [at "));
66 assertThat(causes.get(2).getMessage(),
67 startsWith("Unable to resolve identity (cyclic.identity.test)child-identity-3 and base identity "
68 + "(cyclic.identity.test)child-identity-4 [at "));
69 assertThat(causes.get(3).getMessage(),
70 startsWith("Unable to resolve identity (cyclic.identity.test)child-identity-4 and base identity "
71 + "(cyclic.identity.test)child-identity-1 [at "));
75 void identityTest() throws ReactorException {
76 SchemaContext result = RFC7950Reactors.defaultReactor().newBuild().addSources(IDENTITY_TEST).buildEffective();
77 assertNotNull(result);
79 Module module = result.findModule("identity-test").orElseThrow();
80 var identities = module.getIdentities();
82 assertNotNull(identities);
83 assertEquals(4, identities.size());
85 IdentitySchemaNode root = null;
86 IdentitySchemaNode child1 = null;
87 IdentitySchemaNode child2 = null;
88 IdentitySchemaNode child12 = null;
89 for (IdentitySchemaNode identitySchemaNode : identities) {
90 switch (identitySchemaNode.getQName().getLocalName()) {
92 root = identitySchemaNode;
94 case "child-identity-1":
95 child1 = identitySchemaNode;
97 case "child-identity-2":
98 child2 = identitySchemaNode;
100 case "child-identity-1-2":
101 child12 = identitySchemaNode;
109 assertNotNull(child1);
110 assertNotNull(child2);
111 assertNotNull(child12);
113 assertTrue(root.getBaseIdentities().isEmpty());
115 var rootDerivedIdentities = result.getDerivedIdentities(root);
116 assertEquals(2, rootDerivedIdentities.size());
118 assertTrue(rootDerivedIdentities.contains(child1));
119 assertTrue(rootDerivedIdentities.contains(child2));
120 assertFalse(rootDerivedIdentities.contains(child12));
121 assertNotEquals(child1, child2);
123 assertSame(root, Iterables.getOnlyElement(child1.getBaseIdentities()));
124 assertSame(root, Iterables.getOnlyElement(child2.getBaseIdentities()));
126 assertEquals(0, result.getDerivedIdentities(child2).size());
128 var child1DerivedIdentities = result.getDerivedIdentities(child1);
129 assertEquals(1, child1DerivedIdentities.size());
130 assertTrue(child1DerivedIdentities.contains(child12));
131 assertFalse(child1DerivedIdentities.contains(child1));
133 assertSame(child1, Iterables.getOnlyElement(child12.getBaseIdentities()));
134 assertSame(child12, child1DerivedIdentities.iterator().next());