X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-netconf-connector%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fconfignetconfconnector%2FNetconfMappingTest.java;h=6f9a62af1a4857f6c17d6d62c880248c49da42d0;hp=cd38d3babef700c8cb5b55529bbac71fb5e4c943;hb=55a40f35dcd1c7e38f5315a2035686be12b6c6da;hpb=9c9d6e69da3aff2d0576d8c15ea0fa0692595b6d diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index cd38d3babe..6f9a62af1a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -22,6 +22,12 @@ import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertCo import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -34,23 +40,22 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; - import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import javax.xml.parsers.ParserConfigurationException; - import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; import org.custommonkey.xmlunit.NodeTester; import org.custommonkey.xmlunit.XMLAssert; import org.custommonkey.xmlunit.XMLUnit; +import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.junit.matchers.JUnitMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -72,11 +77,14 @@ import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFacto import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean; import org.opendaylight.controller.config.yang.test.impl.Peers; +import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; +import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit; import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.Lock; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.UnLock; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get; import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig; @@ -85,13 +93,13 @@ import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStore import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; +import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; -import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2; @@ -111,15 +119,9 @@ import org.w3c.dom.Text; import org.w3c.dom.traversal.DocumentTraversal; import org.xml.sax.SAXException; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - public class NetconfMappingTest extends AbstractConfigTest { - private static final Logger logger = LoggerFactory.getLogger(NetconfMappingTest.class); + private static final Logger LOG = LoggerFactory.getLogger(NetconfMappingTest.class); private static final String INSTANCE_NAME = "instance-from-code"; private static final String NETCONF_SESSION_ID = "foo"; @@ -127,6 +129,7 @@ public class NetconfMappingTest extends AbstractConfigTest { private NetconfTestImplModuleFactory factory; private DepTestImplModuleFactory factory2; private IdentityTestModuleFactory factory3; + private TestImplModuleFactory factory4; @Mock YangStoreSnapshot yangStoreSnapshot; @@ -147,8 +150,9 @@ public class NetconfMappingTest extends AbstractConfigTest { this.factory = new NetconfTestImplModuleFactory(); this.factory2 = new DepTestImplModuleFactory(); this.factory3 = new IdentityTestModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2, - this.factory3)); + factory4 = new TestImplModuleFactory(); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2, + this.factory3, factory4)); transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID); } @@ -197,33 +201,33 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Document config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1")); edit("netconfMessages/editConfig_addServiceName.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_addServiceNameOnTest.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); commit(); config = getConfigRunning(); assertCorrectRefNamesForDependencies(config); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_replace_default.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_dep", "ref_dep2")); + assertCorrectServiceNames(config, Collections.emptySet()); edit("netconfMessages/editConfig_remove.xml"); config = getConfigCandidate(); @@ -235,6 +239,12 @@ public class NetconfMappingTest extends AbstractConfigTest { } + @Test + public void testUnLock() throws Exception { + assertTrue(NetconfMessageUtil.isOKMessage(lockCandidate())); + assertTrue(NetconfMessageUtil.isOKMessage(unlockCandidate())); + } + private void assertCorrectRefNamesForDependencies(Document config) throws NodeTestException { NodeList modulesList = config.getElementsByTagName("modules"); assertEquals(1, modulesList.getLength()); @@ -262,8 +272,8 @@ public class NetconfMappingTest extends AbstractConfigTest { nt.performTest(tester, Node.TEXT_NODE); } - private void assertCorrectServiceNames(Document configCandidate, final Set refNames) throws NodeTestException { - + private void assertCorrectServiceNames(Document configCandidate, Set refNames) throws NodeTestException { + final Set refNames2 = new HashSet<>(refNames); NodeList servicesNodes = configCandidate.getElementsByTagName("services"); assertEquals(1, servicesNodes.getLength()); @@ -275,9 +285,8 @@ public class NetconfMappingTest extends AbstractConfigTest { if(element.getNodeName() != null) { if(element.getNodeName().equals("name")) { String elmText = element.getTextContent(); - if(refNames.contains(elmText)) { - refNames.remove(elmText); - return; + if(refNames2.contains(elmText)) { + refNames2.remove(elmText); } else { throw new NodeTestException("Unexpected services defined: " + elmText); } @@ -287,7 +296,8 @@ public class NetconfMappingTest extends AbstractConfigTest { @Override public void noMoreNodes(NodeTest forTest) throws NodeTestException { - assertTrue(refNames.isEmpty()); + assertEquals(Collections.emptySet(), refNames2); + assertTrue(refNames2.toString(), refNames2.isEmpty()); } }; nt.performTest(tester, Node.ELEMENT_NODE); @@ -382,6 +392,16 @@ public class NetconfMappingTest extends AbstractConfigTest { executeOp(commitOp, "netconfMessages/commit.xml"); } + private Document lockCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { + Lock commitOp = new Lock(NETCONF_SESSION_ID); + return executeOp(commitOp, "netconfMessages/lock.xml"); + } + + private Document unlockCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { + UnLock commitOp = new UnLock(NETCONF_SESSION_ID); + return executeOp(commitOp, "netconfMessages/unlock.xml"); + } + private Document getConfigCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional. absent(), transactionProvider, @@ -426,42 +446,42 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, afterReplace); } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespaces() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element simple-long-2 present multiple times with different namespaces"); + assertContainsString(message, "Element simpleInt present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testDifferentNamespaceInTO() throws Exception { try { edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); assertContainsString(message, "Unrecognised elements"); assertContainsString(message, "simple-int2"); assertContainsString(message, "dto_d"); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespacesList() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element binaryLeaf present multiple times with different namespaces"); + assertContainsString(message, "Element allow-user present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } @@ -494,6 +514,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (int i = 0; i < TESTS_COUNT; i++) { String file = String.format(format, i + 1); + LOG.info("Reading {}", file); try { edit(file); } catch (NetconfDocumentedException e) { @@ -564,26 +585,16 @@ public class NetconfMappingTest extends AbstractConfigTest { } private void assertContainsString(String string, String substring) { - assertThat(string, JUnitMatchers.containsString(substring)); + assertThat(string, CoreMatchers.containsString(substring)); } - private void checkEnum(final Document response) { - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); - - String enumName = "extended-enum"; - String enumContent = "TWO"; + private void checkEnum(final Document response) throws Exception { - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - String name = moduleElement.getOnlyChildElement("prefix:name").getTextContent(); - if(name.equals(INSTANCE_NAME)) { - XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); - assertEquals(enumContent, enumAttr.getTextContent()); - return; - } - } + String expectedEnumContent = "TWO"; - fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response)); + XMLAssert.assertXpathEvaluatesTo(expectedEnumContent, + getXpathForNetconfImplSubnode(INSTANCE_NAME,"extended-enum"), + response); } private void checkTestingDeps(Document response) { @@ -591,24 +602,23 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, testingDepsSize); } - private void checkTypeConfigAttribute(Document response) { - - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); - - List expectedValues = Lists.newArrayList("default-string", "configAttributeType"); - Set configAttributeType = Sets.newHashSet(); + private String getXpathForNetconfImplSubnode(String instanceName, String subnode) { + return "/urn:ietf:params:xml:ns:netconf:base:1.0:rpc-reply" + + "/urn:ietf:params:xml:ns:netconf:base:1.0:data" + + "/urn:opendaylight:params:xml:ns:yang:controller:config:modules" + + "/module[name='"+instanceName+"']" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:impl-netconf" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:"+subnode; + } - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getNamespace() != null) { - configAttributeType.add(type.getTextContent()); - } - } - } + private void checkTypeConfigAttribute(Document response) throws Exception { - for (String expectedValue : expectedValues) { - assertTrue(configAttributeType.contains(expectedValue)); + Map namesToTypeValues = ImmutableMap.of("instance-from-code", "configAttributeType", + "test2", "default-string"); + for (Entry nameToExpectedValue : namesToTypeValues.entrySet()) { + XMLAssert.assertXpathEvaluatesTo(nameToExpectedValue.getValue(), + getXpathForNetconfImplSubnode(nameToExpectedValue.getKey(),"type"), + response); } } @@ -668,7 +678,7 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(8 * 4, getElementsSize(response, "inner-inner-running-data")); assertEquals(8 * 4, getElementsSize(response, "deep3")); assertEquals(8 * 4 * 2, getElementsSize(response, "list-of-strings")); - assertEquals(8, getElementsSize(response, "inner-running-data-additional")); + assertEquals(8, getElementsSize(response, "inner-running-data-additional", "urn:opendaylight:params:xml:ns:yang:controller:test:impl")); assertEquals(8, getElementsSize(response, "deep4")); // TODO assert keys @@ -691,7 +701,7 @@ public class NetconfMappingTest extends AbstractConfigTest { } private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { - Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID, transactionProvider); + Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID); return executeOp(getOp, "netconfMessages/get.xml"); } @@ -699,25 +709,29 @@ public class NetconfMappingTest extends AbstractConfigTest { return response.getElementsByTagName(elementName).getLength(); } + private int getElementsSize(Document response, String elementName, String namespace) { + return response.getElementsByTagNameNS(namespace, elementName).getLength(); + } + private Document executeOp(final NetconfOperation op, final String filename) throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { final Document request = XmlFileLoader.xmlFileToDocument(filename); - logger.debug("Executing netconf operation\n{}", XmlUtil.toString(request)); + LOG.debug("Executing netconf operation\n{}", XmlUtil.toString(request)); HandlingPriority priority = op.canHandle(request); Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE); final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT); - logger.debug("Got response\n{}", XmlUtil.toString(response)); + LOG.debug("Got response\n{}", XmlUtil.toString(response)); return response; } private List getYangs() throws FileNotFoundException { List paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang", "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang", "/META-INF/yang/test-types.yang", - "/META-INF/yang/ietf-inet-types.yang"); + "/META-INF/yang/test-groups.yang", "/META-INF/yang/ietf-inet-types.yang"); final Collection yangDependencies = new ArrayList<>(); for (String path : paths) { final InputStream is = Preconditions