From ed458fab4af19a19d5ea52f91264e3e1467cf895 Mon Sep 17 00:00:00 2001 From: Milos Fabian Date: Mon, 14 Apr 2014 11:22:59 +0200 Subject: [PATCH] Bug 491 - Use XmlUnit for xml comparing in junit tests. -comparing XMLs as DOM Documents with XmlUnit -added XmlUnit util class - contains common assertion tests Change-Id: I505c7896e7243873b45c93ea3bf59c941a68924e Signed-off-by: Milos Fabian --- opendaylight/commons/opendaylight/pom.xml | 6 + .../pom.xml | 4 + .../xml/DirectoryStorageAdapterTest.java | 17 +- .../config-persister-file-xml-adapter/pom.xml | 4 + .../file/xml/FileStorageAdapterTest.java | 24 +- .../netconf/config-netconf-connector/pom.xml | 4 + .../NetconfMappingTest.java | 224 ++++++++++-------- .../netconf/impl/MessageParserTest.java | 5 +- opendaylight/netconf/netconf-it/pom.xml | 4 + .../it/NetconfConfigPersisterITTest.java | 76 +++--- .../netconf/it/NetconfMonitoringITTest.java | 11 +- .../it/pax/IdentityRefNetconfTest.java | 23 +- .../src/test/resources/controller.xml | 80 +++---- opendaylight/netconf/netconf-util/pom.xml | 4 + .../netconf/util/test/XmlUnitUtil.java | 117 +++++++++ .../netconfMessages/rpc-reply_ok.xml | 3 + 16 files changed, 395 insertions(+), 211 deletions(-) create mode 100644 opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java create mode 100644 opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_ok.xml diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index d5d7e8e5c4..140a6ddfe1 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -297,6 +297,12 @@ org.eclipse.equinox.launcher 1.3.0.v20120522-1813 + + xmlunit + xmlunit + 1.5 + test + geminiweb diff --git a/opendaylight/config/config-persister-directory-xml-adapter/pom.xml b/opendaylight/config/config-persister-directory-xml-adapter/pom.xml index 30c5247004..2b98f41376 100644 --- a/opendaylight/config/config-persister-directory-xml-adapter/pom.xml +++ b/opendaylight/config/config-persister-directory-xml-adapter/pom.xml @@ -59,6 +59,10 @@ test-jar test + + xmlunit + xmlunit + diff --git a/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java b/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java index da442ef4b2..7af06bd3e3 100644 --- a/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java +++ b/opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java @@ -8,21 +8,26 @@ package org.opendaylight.controller.config.persist.storage.directory.xml; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.File; +import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.SortedSet; -import com.google.common.base.Optional; import org.junit.Test; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.api.Persister; import org.opendaylight.controller.config.persist.test.PropertiesProviderTest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import org.xml.sax.SAXException; + +import com.google.common.base.Optional; public class DirectoryStorageAdapterTest { Persister tested; @@ -95,8 +100,8 @@ public class DirectoryStorageAdapterTest { logger.info("Testing : " + tested.toString()); } - private void assertResult(ConfigSnapshotHolder result, String s, String... caps) { - assertEquals(s, result.getConfigSnapshot().replaceAll("\\s", "")); + private void assertResult(ConfigSnapshotHolder result, String s, String... caps) throws SAXException, IOException { + assertXMLEqual(s, result.getConfigSnapshot()); int i = 0; for (String capFromSnapshot : result.getCapabilities()) { assertEquals(capFromSnapshot, caps[i++]); diff --git a/opendaylight/config/config-persister-file-xml-adapter/pom.xml b/opendaylight/config/config-persister-file-xml-adapter/pom.xml index 8796f0e49d..a5010f0464 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/pom.xml +++ b/opendaylight/config/config-persister-file-xml-adapter/pom.xml @@ -50,6 +50,10 @@ test-jar test + + xmlunit + xmlunit + diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java index 5322f6357a..2bfe70adb8 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java +++ b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java @@ -8,7 +8,12 @@ package org.opendaylight.controller.config.persist.storage.file.xml; -import com.google.common.base.Charsets; +import static junit.framework.Assert.assertFalse; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -16,16 +21,16 @@ import java.nio.file.Files; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; + import junit.framework.Assert; + import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.test.PropertiesProviderTest; -import static junit.framework.Assert.assertFalse; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; + +import com.google.common.base.Charsets; public class FileStorageAdapterTest { @@ -96,8 +101,7 @@ public class FileStorageAdapterTest { List lastConf = storage.loadLastConfigs(); assertEquals(1, lastConf.size()); ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0); - assertEquals("2", - configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", "")); + assertXMLEqual("2", configSnapshotHolder.getConfigSnapshot()); assertEquals(createCaps(), configSnapshotHolder.getCapabilities()); storage = new XmlFileStorageAdapter(); @@ -147,8 +151,7 @@ public class FileStorageAdapterTest { List lastConf = storage.loadLastConfigs(); assertEquals(1, lastConf.size()); ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0); - assertEquals("2", - configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", "")); + assertXMLEqual("2", configSnapshotHolder.getConfigSnapshot()); } @Test @@ -178,8 +181,7 @@ public class FileStorageAdapterTest { List lastConf = storage.loadLastConfigs(); assertEquals(1, lastConf.size()); ConfigSnapshotHolder configSnapshotHolder = lastConf.get(0); - assertEquals("3", - configSnapshotHolder.getConfigSnapshot().replaceAll("\\s", "")); + assertXMLEqual("3", configSnapshotHolder.getConfigSnapshot()); assertFalse(readLines.contains(holder.getConfigSnapshot())); } diff --git a/opendaylight/netconf/config-netconf-connector/pom.xml b/opendaylight/netconf/config-netconf-connector/pom.xml index b37b5babdd..d2a907ba4a 100644 --- a/opendaylight/netconf/config-netconf-connector/pom.xml +++ b/opendaylight/netconf/config-netconf-connector/pom.xml @@ -85,6 +85,10 @@ org.opendaylight.controller commons.logback_settings + + xmlunit + xmlunit + 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 96522712da..9770cc5bee 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 @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -17,6 +18,9 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; +import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; import java.io.FileNotFoundException; import java.io.IOException; @@ -26,6 +30,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -36,7 +41,12 @@ import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import javax.xml.parsers.ParserConfigurationException; -import org.apache.commons.lang3.StringUtils; +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.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -95,7 +105,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.w3c.dom.traversal.DocumentTraversal; import org.xml.sax.SAXException; import com.google.common.base.Optional; @@ -110,6 +123,7 @@ public class NetconfMappingTest extends AbstractConfigTest { private static final String INSTANCE_NAME = "instance-from-code"; private static final String NETCONF_SESSION_ID = "foo"; + private static final String TEST_NAMESPACE= "urn:opendaylight:params:xml:ns:yang:controller:test:impl"; private NetconfTestImplModuleFactory factory; private DepTestImplModuleFactory factory2; private IdentityTestModuleFactory factory3; @@ -182,72 +196,101 @@ public class NetconfMappingTest extends AbstractConfigTest { createModule(INSTANCE_NAME); edit("netconfMessages/editConfig.xml"); - Element config = getConfigCandidate(); - assertCorrectServiceNames(config, 6, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + Document config = getConfigCandidate(); + assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "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_from_code_to_instance-from-code_1")); edit("netconfMessages/editConfig_addServiceName.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "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"); + "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_addServiceNameOnTest.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "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"); + "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); commit(); config = getConfigRunning(); assertCorrectRefNamesForDependencies(config); - assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "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"); + "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_replace_default.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, 2, "ref_dep", "ref_dep2"); + assertCorrectServiceNames(config, Sets.newHashSet("ref_dep", "ref_dep2")); edit("netconfMessages/editConfig_remove.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, 0); + assertCorrectServiceNames(config, Collections.emptySet()); commit(); config = getConfigCandidate(); - assertCorrectServiceNames(config, 0); + assertCorrectServiceNames(config, Collections.emptySet()); } - private void assertCorrectRefNamesForDependencies(Element config) { + private void assertCorrectRefNamesForDependencies(Document config) throws NodeTestException { NodeList modulesList = config.getElementsByTagName("modules"); assertEquals(1, modulesList.getLength()); - Element modules = (Element) modulesList.item(0); + NodeTest nt = new NodeTest((DocumentTraversal) config, modulesList.item(0)); + NodeTester tester = new AbstractNodeTester() { + private int defaultRefNameCount = 0; + private int userRefNameCount = 0; - String trimmedModules = XmlUtil.toString(modules).replaceAll("\\s", ""); - int defaultRefNameCount = StringUtils.countMatches(trimmedModules, "ref_dep2"); - int userRefNameCount = StringUtils.countMatches(trimmedModules, "ref_dep_user_two"); + @Override + public void testText(Text text) throws NodeTestException { + if(text.getData().equals("ref_dep2")) { + defaultRefNameCount++; + } else if(text.getData().equals("ref_dep_user_two")) { + userRefNameCount++; + } + } - assertEquals(0, defaultRefNameCount); - assertEquals(2, userRefNameCount); + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertEquals(0, defaultRefNameCount); + assertEquals(2, userRefNameCount); + } + }; + nt.performTest(tester, Node.TEXT_NODE); } - private void assertCorrectServiceNames(Element configCandidate, int servicesSize, String... refNames) { - NodeList elements = configCandidate.getElementsByTagName("provider"); - assertEquals(servicesSize, elements.getLength()); + private void assertCorrectServiceNames(Document configCandidate, final Set refNames) throws NodeTestException { - NodeList servicesList = configCandidate.getElementsByTagName("services"); - assertEquals(1, servicesList.getLength()); + NodeList servicesNodes = configCandidate.getElementsByTagName("services"); + assertEquals(1, servicesNodes.getLength()); - Element services = (Element) servicesList.item(0); - String trimmedServices = XmlUtil.toString(services).replaceAll("\\s", ""); + NodeTest nt = new NodeTest((DocumentTraversal) configCandidate, servicesNodes.item(0)); + NodeTester tester = new AbstractNodeTester() { - for (String s : refNames) { - assertThat(trimmedServices, JUnitMatchers.containsString(s)); - } + @Override + public void testElement(Element element) throws NodeTestException { + if(element.getNodeName() != null) { + if(element.getNodeName().equals("name")) { + String elmText = element.getTextContent(); + if(refNames.contains(elmText)) { + refNames.remove(elmText); + return; + } else { + throw new NodeTestException("Unexpected services defined: " + elmText); + } + } + } + } + + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertTrue(refNames.isEmpty()); + } + }; + nt.performTest(tester, Node.ELEMENT_NODE); } @Test @@ -257,19 +300,18 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); commit(); - Element response = getConfigRunning(); - String trimmedResponse = XmlUtil.toString(response).replaceAll("\\s", ""); - assertContainsString(trimmedResponse, "0:0:0:0:0:0:0:1"); - assertContainsString(trimmedResponse, "456"); + Document response = getConfigRunning(); + Element ipElement = readXmlToElement("0:0:0:0:0:0:0:1"); + assertContainsElement(response, readXmlToElement("0:0:0:0:0:0:0:1")); + + assertContainsElement(response, readXmlToElement("456")); edit("netconfMessages/editConfig_setUnions.xml"); commit(); response = getConfigRunning(); - - trimmedResponse = XmlUtil.toString(response).replaceAll("\\s", ""); - assertContainsString(trimmedResponse, "127.1.2.3"); - assertContainsString(trimmedResponse, "randomStringForUnion"); + assertContainsElement(response, readXmlToElement("127.1.2.3")); + assertContainsElement(response, readXmlToElement("randomStringForUnion")); } @@ -279,7 +321,7 @@ public class NetconfMappingTest extends AbstractConfigTest { createModule(INSTANCE_NAME); edit("netconfMessages/editConfig.xml"); - Element configCandidate = getConfigCandidate(); + Document configCandidate = getConfigCandidate(); checkBinaryLeafEdited(configCandidate); @@ -289,7 +331,7 @@ public class NetconfMappingTest extends AbstractConfigTest { // check after edit commit(); - Element response = getConfigRunning(); + Document response = getConfigRunning(); checkBinaryLeafEdited(response); checkTypeConfigAttribute(response); @@ -301,17 +343,12 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig_remove.xml"); commit(); - response = getConfigCandidate(); - final String responseFromCandidate = XmlUtil.toString(response).replaceAll("\\s+", ""); - response = getConfigRunning(); - final String responseFromRunning = XmlUtil.toString(response).replaceAll("\\s+", ""); - assertEquals(responseFromCandidate, responseFromRunning); - - final String expectedResult = XmlFileLoader.fileToString("netconfMessages/editConfig_expectedResult.xml") - .replaceAll("\\s+", ""); + assertXMLEqual(getConfigCandidate(), getConfigRunning()); - assertEquals(expectedResult, responseFromRunning); - assertEquals(expectedResult, responseFromCandidate); + final Document expectedResult = XmlFileLoader.xmlFileToDocument("netconfMessages/editConfig_expectedResult.xml"); + XMLUnit.setIgnoreWhitespace(true); + assertXMLEqual(expectedResult, getConfigRunning()); + assertXMLEqual(expectedResult, getConfigCandidate()); edit("netconfMessages/editConfig_none.xml"); closeSession(); @@ -320,12 +357,10 @@ public class NetconfMappingTest extends AbstractConfigTest { verifyNoMoreInteractions(netconfOperationServiceSnapshot); } - private void checkBigDecimal(Element response) { - String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", ""); - - assertContainsString(responseTrimmed, "2.58"); + private void checkBigDecimal(Document response) throws NodeTestException, SAXException, IOException { + assertContainsElement(response, readXmlToElement("2.58")); // Default - assertContainsString(responseTrimmed, "2.00"); + assertContainsElement(response, readXmlToElement("2.00")); } @@ -347,14 +382,14 @@ public class NetconfMappingTest extends AbstractConfigTest { executeOp(commitOp, "netconfMessages/commit.xml"); } - private Element getConfigCandidate() throws ParserConfigurationException, SAXException, IOException, + private Document getConfigCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional. absent(), transactionProvider, configRegistryClient, NETCONF_SESSION_ID); return executeOp(getConfigOp, "netconfMessages/getConfig_candidate.xml"); } - private Element getConfigRunning() throws ParserConfigurationException, SAXException, IOException, + private Document getConfigRunning() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional. absent(), transactionProvider, configRegistryClient, NETCONF_SESSION_ID); @@ -378,7 +413,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); commit(); - Element response = getConfigRunning(); + Document response = getConfigRunning(); final int allInstances = response.getElementsByTagName("module").getLength(); edit("netconfMessages/editConfig_replace_default.xml"); @@ -398,7 +433,7 @@ public class NetconfMappingTest extends AbstractConfigTest { } catch (NetconfDocumentedException e) { String message = e.getMessage(); assertContainsString(message, "Element simple-long-2 present multiple times with different namespaces"); - assertContainsString(message, "urn:opendaylight:params:xml:ns:yang:controller:test:impl"); + assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); throw e; } @@ -424,7 +459,7 @@ public class NetconfMappingTest extends AbstractConfigTest { } catch (NetconfDocumentedException e) { String message = e.getMessage(); assertContainsString(message, "Element binaryLeaf present multiple times with different namespaces"); - assertContainsString(message, "urn:opendaylight:params:xml:ns:yang:controller:test:impl"); + assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); throw e; } @@ -437,7 +472,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml"); commit(); - Element response = getConfigRunning(); + Document response = getConfigRunning(); checkTypeConfigAttribute(response); } @@ -479,7 +514,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); commit(); - Element response = getConfigRunning(); + Document response = getConfigRunning(); final int allInstances = response.getElementsByTagName("instance").getLength(); edit("netconfMessages/editConfig_replace_module.xml"); @@ -508,42 +543,32 @@ public class NetconfMappingTest extends AbstractConfigTest { executeOp(discardOp, "netconfMessages/discardChanges.xml"); } - private void checkBinaryLeafEdited(final Element response) { - String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", ""); - String substring = "YmluYXJ5"; - assertContainsString(responseTrimmed, substring); - substring = "ZGVmYXVsdEJpbg=="; - assertContainsString(responseTrimmed, substring); + private void checkBinaryLeafEdited(final Document response) throws NodeTestException, SAXException, IOException { + assertContainsElement(response, readXmlToElement("YmluYXJ5")); + assertContainsElement(response, readXmlToElement("ZGVmYXVsdEJpbg==")); } - private void checkTypedefs(final Element response) { - String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", ""); + private void checkTypedefs(final Document response) throws NodeTestException, SAXException, IOException { - String substring = "10"; - assertContainsString(responseTrimmed, substring); + assertContainsElement(response, readXmlToElement("10")); // Default - assertContainsString(responseTrimmed, - "1"); + assertContainsElement(response, readXmlToElement("1")); - assertContainsString(responseTrimmed, - "20"); + assertContainsElement(response, readXmlToElement("20")); // Default - assertContainsString(responseTrimmed, - "2"); + assertContainsElement(response, readXmlToElement("2")); - assertContainsString(responseTrimmed, - "TWO"); + assertContainsElement(response, readXmlToElement("TWO")); // Default - assertContainsString(responseTrimmed, - "ONE"); + assertContainsElement(response, readXmlToElement("ONE")); } private void assertContainsString(String string, String substring) { assertThat(string, JUnitMatchers.containsString(substring)); } - private void checkEnum(final Element response) { - XmlElement modulesElement = XmlElement.fromDomElement(response).getOnlyChildElement("data") + private void checkEnum(final Document response) { + XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") .getOnlyChildElement("modules"); String enumName = "extended-enum"; @@ -554,7 +579,6 @@ public class NetconfMappingTest extends AbstractConfigTest { if(name.equals(INSTANCE_NAME)) { XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); assertEquals(enumContent, enumAttr.getTextContent()); - return; } } @@ -562,14 +586,14 @@ public class NetconfMappingTest extends AbstractConfigTest { fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response)); } - private void checkTestingDeps(Element response) { + private void checkTestingDeps(Document response) { int testingDepsSize = response.getElementsByTagName("testing-deps").getLength(); assertEquals(2, testingDepsSize); } - private void checkTypeConfigAttribute(Element response) { + private void checkTypeConfigAttribute(Document response) { - XmlElement modulesElement = XmlElement.fromDomElement(response).getOnlyChildElement("data") + XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") .getOnlyChildElement("modules"); List expectedValues = Lists.newArrayList("default-string", "configAttributeType"); @@ -577,7 +601,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (XmlElement moduleElement : modulesElement.getChildElements("module")) { for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY).equals("") == false) { + if (type.getNamespace() != null) { configAttributeType.add(type.getTextContent()); } } @@ -631,7 +655,7 @@ public class NetconfMappingTest extends AbstractConfigTest { // check after edit commit(); - Element response = get(); + Document response = get(); assertEquals(2/*With runtime beans*/ + 2 /*Without runtime beans*/, getElementsSize(response, "module")); // data from state @@ -651,29 +675,31 @@ public class NetconfMappingTest extends AbstractConfigTest { RuntimeRpc netconf = new RuntimeRpc(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID); response = executeOp(netconf, "netconfMessages/rpc.xml"); - assertContainsString(XmlUtil.toString(response), "testarg1".toUpperCase()); + assertContainsElementWithText(response, "testarg1"); response = executeOp(netconf, "netconfMessages/rpcInner.xml"); - assertContainsString(XmlUtil.toString(response), "ok"); + Document expectedReplyOk = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc-reply_ok.xml"); + XMLUnit.setIgnoreWhitespace(true); + XMLAssert.assertXMLEqual(expectedReplyOk, response); response = executeOp(netconf, "netconfMessages/rpcInnerInner.xml"); - assertContainsString(XmlUtil.toString(response), "true"); + assertContainsElementWithText(response, "true"); response = executeOp(netconf, "netconfMessages/rpcInnerInner_complex_output.xml"); - assertContainsString(XmlUtil.toString(response), "1"); - assertContainsString(XmlUtil.toString(response), "2"); + assertContainsElementWithText(response, "1"); + assertContainsElementWithText(response, "2"); } - private Element get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID, transactionProvider); return executeOp(getOp, "netconfMessages/get.xml"); } - private int getElementsSize(Element response, String elementName) { + private int getElementsSize(Document response, String elementName) { return response.getElementsByTagName(elementName).getLength(); } - private Element executeOp(final NetconfOperation op, final String filename) throws ParserConfigurationException, + private Document executeOp(final NetconfOperation op, final String filename) throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { final Document request = XmlFileLoader.xmlFileToDocument(filename); @@ -685,7 +711,7 @@ public class NetconfMappingTest extends AbstractConfigTest { final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT); logger.debug("Got response\n{}", XmlUtil.toString(response)); - return response.getDocumentElement(); + return response; } private List getYangs() throws FileNotFoundException { diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/MessageParserTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/MessageParserTest.java index d1c0b066d7..e13415b64b 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/MessageParserTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/MessageParserTest.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.impl; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -87,7 +88,7 @@ public class MessageParserTest { NetconfMessage receivedMessage = (NetconfMessage) testChunkChannel.readInbound(); assertNotNull(receivedMessage); - assertTrue(this.msg.getDocument().isEqualNode(receivedMessage.getDocument())); + assertXMLEqual(this.msg.getDocument(), receivedMessage.getDocument()); } @Test @@ -106,6 +107,6 @@ public class MessageParserTest { testChunkChannel.writeInbound(recievedOutbound); NetconfMessage receivedMessage = (NetconfMessage) testChunkChannel.readInbound(); assertNotNull(receivedMessage); - assertTrue(this.msg.getDocument().isEqualNode(receivedMessage.getDocument())); + assertXMLEqual(this.msg.getDocument(), receivedMessage.getDocument()); } } diff --git a/opendaylight/netconf/netconf-it/pom.xml b/opendaylight/netconf/netconf-it/pom.xml index 3ca79be9d9..340e295d52 100644 --- a/opendaylight/netconf/netconf-it/pom.xml +++ b/opendaylight/netconf/netconf-it/pom.xml @@ -141,6 +141,10 @@ ${tinybundles.version} test + + xmlunit + xmlunit + diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java index fc1c73f7b0..8b2af39343 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -7,15 +7,32 @@ */ package org.opendaylight.controller.netconf.it; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; +import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount; +import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument; import io.netty.channel.ChannelFuture; -import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.management.InstanceNotFoundException; +import javax.management.Notification; +import javax.management.NotificationListener; + import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.matchers.JUnitMatchers; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; @@ -32,36 +49,22 @@ import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStore import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator; import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService; import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; -import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.xml.sax.SAXException; -import javax.management.InstanceNotFoundException; -import javax.management.Notification; -import javax.management.NotificationListener; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { @@ -128,15 +131,15 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, 4000, clientDispatcher)) { NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage()); - assertResponse(response, ""); - assertEquals("Expected modules count", expectedModulesSize, modulesSize); - int servicesSize = StringUtils.countMatches(configSnapshot, ""); - assertEquals("Expected services count", expectedServicesSize, servicesSize); + Document configSnapshot = readXmlToDocument(snapshot.getConfigSnapshot()); + assertElementsCount(configSnapshot, "module", expectedModulesSize); + assertElementsCount(configSnapshot, "instance", expectedServicesSize); } @Override diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index e36261c6eb..f581342a9c 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -10,11 +10,11 @@ package org.opendaylight.controller.netconf.it; import com.google.common.base.Charsets; import com.google.common.base.Optional; import com.google.common.collect.Sets; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; import io.netty.channel.ChannelFuture; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.matchers.JUnitMatchers; import org.mockito.Mock; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; @@ -165,8 +165,13 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { sock.close(); - org.junit.Assert.assertThat(responseBuilder.toString(), JUnitMatchers.containsString("urn:ietf:params:netconf:capability:candidate:1.0")); - org.junit.Assert.assertThat(responseBuilder.toString(), JUnitMatchers.containsString("tomas")); + String helloMsg = responseBuilder.substring(0, responseBuilder.indexOf(separator)); + Document doc = XmlUtil.readXmlToDocument(helloMsg); + assertContainsElementWithText(doc, "urn:ietf:params:netconf:capability:candidate:1.0"); + + String replyMsg = responseBuilder.substring(responseBuilder.indexOf(separator) + separator.length()); + doc = XmlUtil.readXmlToDocument(replyMsg); + assertContainsElementWithText(doc, "tomas"); } private void assertSessionElementsInResponse(Document document, int i) { diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java index 18275ad78b..266b245b7f 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java @@ -19,13 +19,16 @@ import static org.ops4j.pax.exam.CoreOptions.options; import static org.ops4j.pax.exam.CoreOptions.streamBundle; import static org.ops4j.pax.exam.CoreOptions.systemPackages; import static org.ops4j.pax.exam.CoreOptions.systemProperty; +import io.netty.channel.nio.NioEventLoopGroup; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import javax.inject.Inject; import javax.xml.parsers.ParserConfigurationException; -import com.google.common.base.Preconditions; -import com.google.common.base.Throwables; -import io.netty.channel.nio.NioEventLoopGroup; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -46,10 +49,8 @@ import org.ops4j.pax.tinybundles.core.TinyBundles; import org.osgi.framework.Constants; import org.xml.sax.SAXException; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; +import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; @Ignore @RunWith(PaxExam.class) @@ -125,10 +126,10 @@ public class IdentityRefNetconfTest { sendMessage(edit, netconfClient); sendMessage(commit, netconfClient); sendMessage(getConfig, netconfClient, "id-test", - "prefix:test-identity1", - "prefix:test-identity2", - "prefix:test-identity2", - "prefix:test-identity1"); + "prefix:test-identity1", + "prefix:test-identity2", + "prefix:test-identity2", + "prefix:test-identity1"); clientDispatcher.close(); } catch (Exception e) { diff --git a/opendaylight/netconf/netconf-it/src/test/resources/controller.xml b/opendaylight/netconf/netconf-it/src/test/resources/controller.xml index 664a30daa5..96efc10403 100644 --- a/opendaylight/netconf/netconf-it/src/test/resources/controller.xml +++ b/opendaylight/netconf/netconf-it/src/test/resources/controller.xml @@ -17,56 +17,56 @@ - prefix:impl-identity-test - id-test + prefix:impl-identity-test + id-test - prefix:test-identity2 + prefix:test-identity2 - prefix:test-identity2 - prefix:test-identity1 + prefix:test-identity2 + prefix:test-identity1 - prefix:test-identity1 - prefix:test-identity2 + prefix:test-identity1 + prefix:test-identity2 - prefix:test-identity1 + prefix:test-identity1 - prefix:binding-broker-impl - binding-broker-impl + prefix:binding-broker-impl + binding-broker-impl - prefix:binding-notification-service + prefix:binding-notification-service ref_binding-notification-broker - prefix:binding-data-broker + prefix:binding-data-broker ref_binding-data-broker - prefix:runtime-generated-mapping - runtime-mapping-singleton + prefix:runtime-generated-mapping + runtime-mapping-singleton - prefix:binding-notification-broker - binding-notification-broker + prefix:binding-notification-broker + binding-notification-broker - prefix:binding-data-broker - binding-data-broker + prefix:binding-data-broker + binding-data-broker - prefix:dom-broker-osgi-registry + prefix:dom-broker-osgi-registry ref_dom-broker - prefix:binding-dom-mapping-service + prefix:binding-dom-mapping-service ref_runtime-mapping-singleton - prefix:logback - singleton + prefix:logback + singleton DEBUG console @@ -79,95 +79,95 @@ - prefix:schema-service-singleton - yang-schema-service + prefix:schema-service-singleton + yang-schema-service - prefix:hash-map-data-store - hash-map-data-store + prefix:hash-map-data-store + hash-map-data-store - prefix:dom-broker-impl - dom-broker + prefix:dom-broker-impl + dom-broker - prefix:dom-data-store + prefix:dom-data-store ref_hash-map-data-store - prefix:schema-service + prefix:schema-service ref_yang-schema-service /modules/module[type='schema-service-singleton'][name='yang-schema-service'] - prefix:dom-data-store + prefix:dom-data-store ref_hash-map-data-store /modules/module[type='hash-map-data-store'][name='hash-map-data-store'] - prefix:dom-broker-osgi-registry + prefix:dom-broker-osgi-registry ref_dom-broker /modules/module[type='dom-broker-impl'][name='dom-broker'] - prefix:testing + prefix:testing ref_id-test /modules/module[type='impl-identity-test'][name='id-test'] - prefix:binding-dom-mapping-service + prefix:binding-dom-mapping-service ref_runtime-mapping-singleton /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] - prefix:binding-data-consumer-broker + prefix:binding-data-consumer-broker ref_binding-data-broker /modules/module[type='binding-data-broker'][name='binding-data-broker'] - prefix:binding-rpc-registry + prefix:binding-rpc-registry ref_binding-broker-impl /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - prefix:binding-notification-service + prefix:binding-notification-service ref_binding-notification-broker /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] - prefix:binding-broker-osgi-registry + prefix:binding-broker-osgi-registry ref_binding-broker-impl /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - prefix:binding-notification-subscription-service + prefix:binding-notification-subscription-service ref_binding-notification-broker /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] - prefix:binding-data-broker + prefix:binding-data-broker ref_binding-data-broker /modules/module[type='binding-data-broker'][name='binding-data-broker'] diff --git a/opendaylight/netconf/netconf-util/pom.xml b/opendaylight/netconf/netconf-util/pom.xml index d623dd9796..b75d3382b1 100644 --- a/opendaylight/netconf/netconf-util/pom.xml +++ b/opendaylight/netconf/netconf-util/pom.xml @@ -50,6 +50,10 @@ org.opendaylight.controller.thirdparty ganymed + + xmlunit + xmlunit + diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java new file mode 100644 index 0000000000..e8a453e5d3 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java @@ -0,0 +1,117 @@ +/* + * 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.controller.netconf.util.test; + +import static org.custommonkey.xmlunit.XMLAssert.assertNodeTestPasses; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.custommonkey.xmlunit.AbstractNodeTester; +import org.custommonkey.xmlunit.NodeTest; +import org.custommonkey.xmlunit.NodeTestException; +import org.custommonkey.xmlunit.NodeTester; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.Text; + +public class XmlUnitUtil { + + private XmlUnitUtil() {} + + public static void assertContainsElementWithText(final Document doc, final String textToFind) throws NodeTestException { + NodeTest nt = new NodeTest(doc); + NodeTester tester = new AbstractNodeTester() { + + boolean textFound = false; + + @Override + public void testText(Text text) throws NodeTestException { + if(!textFound) { + if (text.getData().equalsIgnoreCase(textToFind)) { + textFound = true; + } + } + } + + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertTrue(textFound); + } + }; + assertNodeTestPasses(nt, tester, new short[]{Node.TEXT_NODE}, true); + } + + public static void assertContainsElement(final Document doc, final Element testElement) throws NodeTestException { + NodeTest nt = new NodeTest(doc); + NodeTester tester = new AbstractNodeTester() { + + private boolean elementFound = false; + + @Override + public void testElement(Element element) throws NodeTestException { + if (!elementFound) { + if(element.isEqualNode(testElement)) { + elementFound = true; + } + } + } + + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertTrue(elementFound); + } + }; + assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true); + } + + public static void assertContainsElementWithName(final Document doc, final String elementName) throws NodeTestException { + NodeTest nt = new NodeTest(doc); + NodeTester tester = new AbstractNodeTester() { + + private boolean elementFound = false; + + @Override + public void testElement(Element element) throws NodeTestException { + if (!elementFound) { + if (element.getNodeName() != null && element.getNodeName().equals(elementName)) { + elementFound = true; + } + } + } + + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertTrue(elementFound); + } + }; + assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true); + } + + public static void assertElementsCount(final Document doc, final String elementName, final int expectedCount) { + NodeTest nt = new NodeTest(doc); + NodeTester tester = new AbstractNodeTester() { + + private int elementFound = 0; + + @Override + public void testElement(Element element) throws NodeTestException { + if (element.getNodeName() != null && element.getNodeName().equals(elementName)) { + elementFound++; + } + } + + @Override + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + assertEquals(expectedCount, elementFound); + } + }; + assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true); + } +} diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_ok.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_ok.xml new file mode 100644 index 0000000000..59496335f5 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_ok.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file -- 2.36.6