/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.it.yang.runtime.stmt.parser.retest; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableSet; import java.io.InputStream; import java.net.URI; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Test; import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl; import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; public class MultipleRevisionsSupportTest { public static final YangModuleInfo TOPOLOGY_OLD_MODULE = org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.$YangModuleInfoImpl .getInstance(); public static final YangModuleInfo TOPOLOGY_NEW_MODULE = org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.$YangModuleInfoImpl .getInstance(); public static final Set<YangModuleInfo> DEPENDENCIES = ImmutableSet.<YangModuleInfo> builder() // .addAll(TOPOLOGY_OLD_MODULE.getImportedModules()) // .addAll(TOPOLOGY_NEW_MODULE.getImportedModules()).build(); @Test public void dependenciesOlderNewer() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .addAll(toInputStreams(DEPENDENCIES)) // .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } @Test public void dependenciesNewerOlder() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .addAll(toInputStreams(DEPENDENCIES)) // .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } @Test public void newerOlderDependencies() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .addAll(toInputStreams(DEPENDENCIES)) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } @Test public void newerDependenciesOlder() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .addAll(toInputStreams(DEPENDENCIES)) // .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } @Test public void OlderNewerDependencies() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .addAll(toInputStreams(DEPENDENCIES)) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } @Test public void olderDependenciesNewer() throws Exception { List<InputStream> streams = ImmutableList.<InputStream> builder()// .add(TOPOLOGY_OLD_MODULE.getModuleSourceStream()) // .add(TOPOLOGY_NEW_MODULE.getModuleSourceStream()) // .addAll(toInputStreams(DEPENDENCIES)) // .build(); SchemaContext schemaContext = contextVerified(streams); verifySchemaDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); verifyBindingDifference(schemaContext, TOPOLOGY_OLD_MODULE, TOPOLOGY_NEW_MODULE); } private SchemaContext contextVerified(final List<InputStream> streams) throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); return reactor.buildEffective(streams); } private void verifyBindingDifference(final SchemaContext schemaContext, final YangModuleInfo oldModule, final YangModuleInfo newModule) { generatedTypesVerified(schemaContext, oldModule, newModule); } private Map<Module, ModuleContext> generatedTypesVerified(final SchemaContext schemaContext, final YangModuleInfo oldModule, final YangModuleInfo newModule) { BindingGeneratorImpl generator = new BindingGeneratorImpl(); generator.generateTypes(schemaContext); return generator.getModuleContexts(); } private void verifySchemaDifference(final SchemaContext context, final YangModuleInfo topologyOldModule, final YangModuleInfo topologyNewModule) { Module oldModel = context.findModuleByNamespaceAndRevision(// URI.create(TOPOLOGY_OLD_MODULE.getNamespace()), QName.parseRevision(TOPOLOGY_OLD_MODULE.getRevision())); Module newModel = context.findModuleByNamespaceAndRevision(// URI.create(TOPOLOGY_NEW_MODULE.getNamespace()), QName.parseRevision(TOPOLOGY_NEW_MODULE.getRevision())); SchemaNode oldNode = findSchemaNode(oldModel, "network-topology", "topology", "link"); SchemaNode newNode = findSchemaNode(newModel, "network-topology", "topology", "link"); assertNotNull(oldNode); assertNotNull(newNode); assertDeepRevision(TOPOLOGY_OLD_MODULE.getRevision(), oldNode); assertDeepRevision(TOPOLOGY_NEW_MODULE.getRevision(), newNode); } private static void assertDeepRevision(final String revision, final SchemaNode node) { assertEquals("Wrong revision: " + node.getPath(), revision, node.getQName().getFormattedRevision()); if (node instanceof DataNodeContainer) { for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) { assertDeepRevision(revision, child); } } else if (node instanceof ChoiceSchemaNode) { for (DataSchemaNode child : ((ChoiceSchemaNode) node).getCases()) { assertDeepRevision(revision, child); } } } private static final SchemaNode findSchemaNode(final DataNodeContainer container, final String... pathArgs) { DataNodeContainer previous = container; SchemaNode result = (container instanceof SchemaNode) ? (SchemaNode) container : null; for (String arg : pathArgs) { if (previous == null) { return null; } for (DataSchemaNode child : previous.getChildNodes()) { if (child.getQName().getLocalName().equals(arg)) { if (child instanceof DataNodeContainer) { previous = (DataNodeContainer) child; } else { previous = null; } result = child; break; } } } return result; } private static final Iterable<? extends InputStream> toInputStreams(final Set<YangModuleInfo> moduleInfos) throws Exception { Builder<InputStream> streams = ImmutableList.<InputStream> builder(); for (YangModuleInfo yangModuleInfo : moduleInfos) { streams.add(yangModuleInfo.getModuleSourceStream()); } return streams.build(); } }