Merge branch 'master' of ../controller
[yangtools.git] / integration-test / yang-runtime-tests / src / test / java / org / opendaylight / yangtools / it / yang / runtime / stmt / parser / retest / MultipleRevisionsSupportTest.java
1 /*
2  * Copyright (c) 2014 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.yangtools.it.yang.runtime.stmt.parser.retest;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12
13 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
14 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
15
16 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
17 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
18 import com.google.common.collect.ImmutableList;
19 import com.google.common.collect.ImmutableList.Builder;
20 import com.google.common.collect.ImmutableSet;
21 import java.io.InputStream;
22 import java.net.URI;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26 import org.junit.Test;
27 import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
28 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
29 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
33 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.Module;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
37
38 public class MultipleRevisionsSupportTest {
39
40     public static final YangModuleInfo TOPOLOGY_OLD_MODULE = org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.$YangModuleInfoImpl
41             .getInstance();
42     public static final YangModuleInfo TOPOLOGY_NEW_MODULE = org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.$YangModuleInfoImpl
43             .getInstance();
44
45     public static final Set<YangModuleInfo> DEPENDENCIES = ImmutableSet.<YangModuleInfo> builder() //
46             .addAll(TOPOLOGY_OLD_MODULE.getImportedModules()) //
47             .addAll(TOPOLOGY_NEW_MODULE.getImportedModules()).build();
48
49     @Test
50     public void dependenciesOlderNewer() throws Exception {
51         List<InputStream> streams = ImmutableList.<InputStream> builder()//
52                 .addAll(toInputStreams(DEPENDENCIES)) //
53                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
54                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
55                 .build();
56         SchemaContext schemaContext = contextVerified(streams);
57         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
58         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
59     }
60
61     @Test
62     public void dependenciesNewerOlder() throws Exception {
63         List<InputStream> streams = ImmutableList.<InputStream> builder()//
64                 .addAll(toInputStreams(DEPENDENCIES)) //
65                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
66                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
67                 .build();
68         SchemaContext schemaContext = contextVerified(streams);
69         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
70         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
71     }
72
73     @Test
74     public void newerOlderDependencies() throws Exception {
75         List<InputStream> streams = ImmutableList.<InputStream> builder()//
76                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
77                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
78                 .addAll(toInputStreams(DEPENDENCIES)) //
79                 .build();
80         SchemaContext schemaContext = contextVerified(streams);
81         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
82         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
83     }
84
85     @Test
86     public void newerDependenciesOlder() throws Exception {
87         List<InputStream> streams = ImmutableList.<InputStream> builder()//
88                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
89                 .addAll(toInputStreams(DEPENDENCIES)) //
90                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
91                 .build();
92         SchemaContext schemaContext = contextVerified(streams);
93         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
94         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
95     }
96
97     @Test
98     public void OlderNewerDependencies() throws Exception {
99         List<InputStream> streams = ImmutableList.<InputStream> builder()//
100                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
101                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
102                 .addAll(toInputStreams(DEPENDENCIES)) //
103                 .build();
104         SchemaContext schemaContext = contextVerified(streams);
105         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
106         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
107     }
108
109     @Test
110     public void olderDependenciesNewer() throws Exception {
111         List<InputStream> streams = ImmutableList.<InputStream> builder()//
112                 .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) //
113                 .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) //
114                 .addAll(toInputStreams(DEPENDENCIES)) //
115                 .build();
116         SchemaContext schemaContext = contextVerified(streams);
117         verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
118         verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE);
119     }
120
121     private SchemaContext contextVerified(final List<InputStream> streams) throws SourceException, ReactorException {
122         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
123                 .newBuild();
124         return reactor.buildEffective(streams);
125     }
126
127     private void verifyBindingDifference(final SchemaContext schemaContext, final YangModuleInfo oldModule, final YangModuleInfo newModule) {
128         generatedTypesVerified(schemaContext, oldModule, newModule);
129     }
130
131     private Map<Module, ModuleContext> generatedTypesVerified(final SchemaContext schemaContext, final YangModuleInfo oldModule,
132             final YangModuleInfo newModule) {
133         BindingGeneratorImpl generator = new BindingGeneratorImpl();
134         generator.generateTypes(schemaContext);
135         return generator.getModuleContexts();
136     }
137
138     private void verifySchemaDifference(final SchemaContext context, final YangModuleInfo topologyOldModule,
139             final YangModuleInfo topologyNewModule) {
140         Module oldModel = context.findModuleByNamespaceAndRevision(//
141                 URI.create(TOPOLOGY_OLD_MODULE.getNamespace()), QName.parseRevision(TOPOLOGY_OLD_MODULE.getRevision()));
142
143         Module newModel = context.findModuleByNamespaceAndRevision(//
144                 URI.create(TOPOLOGY_NEW_MODULE.getNamespace()), QName.parseRevision(TOPOLOGY_NEW_MODULE.getRevision()));
145
146         SchemaNode oldNode = findSchemaNode(oldModel, "network-topology", "topology", "link");
147         SchemaNode newNode = findSchemaNode(newModel, "network-topology", "topology", "link");
148
149         assertNotNull(oldNode);
150         assertNotNull(newNode);
151
152         assertDeepRevision(TOPOLOGY_OLD_MODULE.getRevision(), oldNode);
153         assertDeepRevision(TOPOLOGY_NEW_MODULE.getRevision(), newNode);
154     }
155
156     private static void assertDeepRevision(final String revision, final SchemaNode node) {
157         assertEquals("Wrong revision: " + node.getPath(), revision, node.getQName().getFormattedRevision());
158         if (node instanceof DataNodeContainer) {
159             for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) {
160                 assertDeepRevision(revision, child);
161             }
162         } else if (node instanceof ChoiceSchemaNode) {
163             for (DataSchemaNode child : ((ChoiceSchemaNode) node).getCases()) {
164                 assertDeepRevision(revision, child);
165             }
166         }
167     }
168
169     private static final SchemaNode findSchemaNode(final DataNodeContainer container, final String... pathArgs) {
170         DataNodeContainer previous = container;
171
172         SchemaNode result = (container instanceof SchemaNode) ? (SchemaNode) container : null;
173         for (String arg : pathArgs) {
174             if (previous == null) {
175                 return null;
176             }
177             for (DataSchemaNode child : previous.getChildNodes()) {
178                 if (child.getQName().getLocalName().equals(arg)) {
179                     if (child instanceof DataNodeContainer) {
180                         previous = (DataNodeContainer) child;
181                     } else {
182                         previous = null;
183                     }
184                     result = child;
185                     break;
186                 }
187             }
188         }
189         return result;
190     }
191
192     private static final Iterable<? extends InputStream> toInputStreams(final Set<YangModuleInfo> moduleInfos)
193             throws Exception {
194         Builder<InputStream> streams = ImmutableList.<InputStream> builder();
195         for (YangModuleInfo yangModuleInfo : moduleInfos) {
196             streams.add(yangModuleInfo.getModuleSourceStream());
197         }
198         return streams.build();
199     }
200
201 }