X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fmdsal-netconf-connector%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fmdsal%2Fconnector%2Fops%2FNetconfMDSalMappingTest.java;h=3e17c16679eb839774e907f2b125afea54c0e39c;hb=refs%2Fchanges%2F13%2F23413%2F26;hp=ca9948a1a07ba96c982b61401699557e946f0f03;hpb=95771c01e72fca4414c3b4d75734126d7c53f6df;p=controller.git diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java index ca9948a1a0..3e17c16679 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java @@ -13,43 +13,53 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.base.Preconditions; import com.google.common.io.ByteSource; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.EnumMap; import java.util.List; import java.util.concurrent.ExecutorService; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import org.custommonkey.xmlunit.DetailedDiff; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLUnit; -import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker; +import org.opendaylight.controller.config.util.xml.DocumentedException; +import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity; +import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag; +import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType; +import org.opendaylight.controller.config.util.xml.XmlElement; +import org.opendaylight.controller.config.util.xml.XmlUtil; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; -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.mdsal.connector.CurrentSchemaContext; import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider; import org.opendaylight.controller.netconf.mdsal.connector.ops.get.Get; import org.opendaylight.controller.netconf.mdsal.connector.ops.get.GetConfig; +import org.opendaylight.controller.netconf.util.test.NetconfXmlUnitRecursiveQualifier; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; -import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.core.spi.data.DOMStore; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.util.concurrent.SpecialExecutors; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; @@ -69,6 +79,22 @@ public class NetconfMDSalMappingTest { private static final String RPC_REPLY_ELEMENT = "rpc-reply"; private static final String DATA_ELEMENT = "data"; + private static final String FILTER_NODE = "filter"; + private static final String GET_CONFIG = "get-config"; + private static final QName TOP = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "top"); + private static final QName USERS = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "users"); + private static final QName USER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "user"); + private static final QName MODULES = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "modules"); + private static final QName AUGMENTED_CONTAINER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "augmented-container"); + private static final QName AUGMENTED_STRING_IN_CONT = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "identifier"); + private static final QName CHOICE_NODE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "choice-node"); + private static final QName AUGMENTED_CASE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "augmented-case"); + private static final QName CHOICE_WRAPPER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "choice-wrapper"); + private static final QName INNER_CHOICE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "inner-choice"); + private static final QName INNER_CHOICE_TEXT = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "text"); + + private static final YangInstanceIdentifier AUGMENTED_CONTAINER_IN_MODULES = + YangInstanceIdentifier.builder().node(TOP).node(MODULES).build().node(new AugmentationIdentifier(Collections.singleton(AUGMENTED_CONTAINER))); private static Document RPC_REPLY_OK = null; @@ -87,7 +113,6 @@ public class NetconfMDSalMappingTest { private TransactionProvider transactionProvider = null; - @Before public void setUp() throws Exception { @@ -96,7 +121,7 @@ public class NetconfMDSalMappingTest { this.schemaContext = parseSchemas(getYangSchemas()); schemaContext.getModules(); - SchemaService schemaService = createSchemaService(); + final SchemaService schemaService = createSchemaService(); final DOMStore operStore = InMemoryDOMDataStoreFactory.create("DOM-OPER", schemaService); final DOMStore configStore = InMemoryDOMDataStoreFactory.create("DOM-CFG", schemaService); @@ -108,7 +133,7 @@ public class NetconfMDSalMappingTest { ExecutorService listenableFutureExecutor = SpecialExecutors.newBlockingBoundedCachedThreadPool( 16, 16, "CommitFutures"); - ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor); + final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor); this.transactionProvider = new TransactionProvider(cdb, sessionIdForReporting); this.currentSchemaContext = new CurrentSchemaContext(schemaService); @@ -116,15 +141,45 @@ public class NetconfMDSalMappingTest { @Test public void testEmptyDatastore() throws Exception { + assertEmptyDatastore(get()); + assertEmptyDatastore(getConfigCandidate()); + assertEmptyDatastore(getConfigRunning()); + } - Document response = getConfigRunning(); - assertEmptyDatastore(response); + @Test + public void testDiscard() throws Exception { - response = getConfigCandidate(); - assertEmptyDatastore(response); + try { + discardChanges(); + fail("Should have failed, need to execute an edit before discard"); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.operation_failed); + assertTrue(e.getErrorType() == ErrorType.application); + } + } + + @Test + public void testIncorrectGet() throws Exception { + + try { + executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_getConfig.xml"); + fail("Should have failed, this is an incorrect request"); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.operation_failed); + assertTrue(e.getErrorType() == ErrorType.application); + } + + try { + executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_namespace_getConfig.xml"); + fail("Should have failed, this is an incorrect request"); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.operation_failed); + assertTrue(e.getErrorType() == ErrorType.application); + } - response = get(); - assertEmptyDatastore(response); } @@ -132,9 +187,9 @@ public class NetconfMDSalMappingTest { public void testEditRunning() throws Exception { try { - edit("messages/mapping/editConfig_running.xml"); + edit("messages/mapping/editConfigs/editConfig_running.xml"); fail("Should have failed - edit config on running datastore is not supported"); - } catch (NetconfDocumentedException e) { + } catch (DocumentedException e) { assertTrue(e.getErrorSeverity() == ErrorSeverity.error); assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported); assertTrue(e.getErrorType() == ErrorType.protocol); @@ -145,8 +200,8 @@ public class NetconfMDSalMappingTest { @Test public void testCandidateTransaction() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_merge_n1.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_n1_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml")); assertEmptyDatastore(getConfigRunning()); verifyResponse(discardChanges(), RPC_REPLY_OK); @@ -157,11 +212,11 @@ public class NetconfMDSalMappingTest { @Test public void testEditWithCommit() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_merge_n1.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_n1_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml")); verifyResponse(commit(), RPC_REPLY_OK); - verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_n1_control.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml")); deleteDatastore(); @@ -170,14 +225,14 @@ public class NetconfMDSalMappingTest { @Test public void testMultipleEditsWithMerge() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_control_1.xml")); - verifyResponse(edit("messages/mapping/editConfig_merge_single_1.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_control_2.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_1.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml")); assertEmptyDatastore(getConfigRunning()); verifyResponse(commit(), RPC_REPLY_OK); - verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_control_2.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml")); deleteDatastore(); @@ -186,26 +241,26 @@ public class NetconfMDSalMappingTest { @Test public void testMoreComplexEditConfigs() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK); - verifyResponse(edit("messages/mapping/editConfig_merge_single_1.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK); - verifyResponse(edit("messages/mapping/editConfig_merge_multiple_2.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_after_more_complex_merge.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_2.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge.xml")); - verifyResponse(edit("messages/mapping/editConfig_merge_multiple_3.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_after_more_complex_merge_2.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_3.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge_2.xml")); - verifyResponse(edit("messages/mapping/editConfig_merge_multiple_4_replace.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_after_replace.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_4_replace.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml")); verifyResponse(commit(), RPC_REPLY_OK); - verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_multiple_after_replace.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml")); - verifyResponse(edit("messages/mapping/editConfig_replace_default.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_replace_default_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_replace_default.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_replace_default_control.xml")); verifyResponse(commit(), RPC_REPLY_OK); - verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_replace_default_control.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_replace_default_control.xml")); deleteDatastore(); @@ -219,11 +274,21 @@ public class NetconfMDSalMappingTest { try { lock(); fail("Should have failed - locking of running datastore is not supported"); - } catch (NetconfDocumentedException e) { + } catch (DocumentedException e) { assertTrue(e.getErrorSeverity() == ErrorSeverity.error); assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported); assertTrue(e.getErrorType() == ErrorType.application); } + + + try { + lockWithoutTarget(); + fail("Should have failed, target is missing"); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.invalid_value); + assertTrue(e.getErrorType() == ErrorType.application); + } } @Test @@ -234,23 +299,33 @@ public class NetconfMDSalMappingTest { try { unlock(); fail("Should have failed - unlocking of running datastore is not supported"); - } catch (NetconfDocumentedException e) { + } catch (DocumentedException e) { assertTrue(e.getErrorSeverity() == ErrorSeverity.error); assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported); assertTrue(e.getErrorType() == ErrorType.application); } + + try { + unlockWithoutTarget(); + fail("Should have failed, target is missing"); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.invalid_value); + assertTrue(e.getErrorType() == ErrorType.application); + } } @Test public void testEditWithCreate() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_create.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_n1_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_create.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_create_n1_control.xml")); + try { - edit("messages/mapping/editConfig_create.xml"); + edit("messages/mapping/editConfigs/editConfig_create.xml"); fail("Create should have failed - data already exists"); - } catch (NetconfDocumentedException e) { + } catch (DocumentedException e) { assertTrue(e.getErrorSeverity() == ErrorSeverity.error); assertTrue(e.getErrorTag() == ErrorTag.data_exists); assertTrue(e.getErrorType() == ErrorType.protocol); @@ -267,9 +342,9 @@ public class NetconfMDSalMappingTest { assertEmptyDatastore(getConfigRunning()); try { - edit("messages/mapping/editConfig_delete-root.xml"); + edit("messages/mapping/editConfigs/editConfig_delete-top.xml"); fail("Delete should have failed - data is missing"); - } catch (NetconfDocumentedException e) { + } catch (DocumentedException e) { assertTrue(e.getErrorSeverity() == ErrorSeverity.error); assertTrue(e.getErrorTag() == ErrorTag.data_missing); assertTrue(e.getErrorType() == ErrorType.protocol); @@ -280,28 +355,183 @@ public class NetconfMDSalMappingTest { @Test public void testEditMissingDefaultOperation() throws Exception { - verifyResponse(edit("messages/mapping/editConfig_merge_missing_default-operation_1.xml"), RPC_REPLY_OK); - verifyResponse(edit("messages/mapping/editConfig_merge_missing_default-operation_2.xml"), RPC_REPLY_OK); - verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_missing_default-operation_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_1.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_2.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml")); verifyResponse(commit(), RPC_REPLY_OK); - verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_merge_missing_default-operation_control.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml")); deleteDatastore(); } + public static void printDocument(Document doc) throws IOException, TransformerException { + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(doc), + new StreamResult(writer)); + LOG.warn(writer.getBuffer().toString()); + } + + @Test + public void testEditConfigWithMultipleOperations() throws Exception { + deleteDatastore(); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_setup.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_1.xml"), RPC_REPLY_OK); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_2.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_2_control.xml")); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_leaf_operations.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_control.xml")); + + deleteDatastore(); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_setup.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_default-replace.xml"), RPC_REPLY_OK); + + try { + edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_create_existing.xml"); + fail(); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.data_exists); + assertTrue(e.getErrorType() == ErrorType.protocol); + } + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations_control.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_remove-non-existing.xml"), RPC_REPLY_OK); + + try { + edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete-non-existing.xml"); + fail(); + } catch (DocumentedException e) { + assertTrue(e.getErrorSeverity() == ErrorSeverity.error); + assertTrue(e.getErrorTag() == ErrorTag.data_missing); + assertTrue(e.getErrorType() == ErrorType.protocol); + } + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup-control.xml")); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2-control.xml")); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_delete.xml"), RPC_REPLY_OK); + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations_control.xml")); + + deleteDatastore(); + } + + @Test + public void testFiltering() throws Exception { + + assertEmptyDatastore(getConfigCandidate()); + assertEmptyDatastore(getConfigRunning()); + + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-config-empty-filter.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml")); + verifyResponse(getWithFilter("messages/mapping/filters/get-empty-filter.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml")); + + verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml")); + verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml")); + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-users.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml")); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup.xml"), RPC_REPLY_OK); + verifyResponse(commit(), RPC_REPLY_OK); + + //TODO uncomment these tests once we can parse KeyedListNode as a selection node, currently you cannot use a KeyedList as a selection node in filter +// verifyFilterIdentifier("messages/mapping/filters/get-filter-alluser.xml", +// YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build()); + verifyFilterIdentifier("messages/mapping/filters/get-filter-company-info.xml", + YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build()); + verifyFilterIdentifier("messages/mapping/filters/get-filter-modules-and-admin.xml", + YangInstanceIdentifier.builder().node(TOP).build()); + verifyFilterIdentifier("messages/mapping/filters/get-filter-only-names-types.xml", + YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build()); +// verifyFilterIdentifier("messages/mapping/filters/get-filter-specific-module-type-and-user.xml", +// YangInstanceIdentifier.builder().node(TOP).build()); +// verifyFilterIdentifier("messages/mapping/filters/get-filter-superuser.xml", +// YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build()); + verifyFilterIdentifier("messages/mapping/filters/get-filter-users.xml", + YangInstanceIdentifier.builder().node(TOP).node(USERS).build()); + + YangInstanceIdentifier ident = YangInstanceIdentifier. + builder(AUGMENTED_CONTAINER_IN_MODULES). + node(AUGMENTED_CONTAINER). + node(AUGMENTED_STRING_IN_CONT).build(); + + verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-string.xml", ident); + verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case.xml", + YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(AUGMENTED_CASE).build()); + + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case.xml")); + verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup2.xml"), RPC_REPLY_OK); + verifyResponse(commit(), RPC_REPLY_OK); + + verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml", + YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).build()); + verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-case.xml", + YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).node(INNER_CHOICE).node(INNER_CHOICE_TEXT).build()); + + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-string.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-string.xml")); + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml")); + verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-case.xml"), + XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml")); + + verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-top.xml"), RPC_REPLY_OK); + verifyResponse(commit(), RPC_REPLY_OK); + + } + + private void verifyFilterIdentifier(String resource, YangInstanceIdentifier identifier) throws Exception{ + TestingGetConfig getConfig = new TestingGetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider); + Document request = XmlFileLoader.xmlFileToDocument(resource); + YangInstanceIdentifier iid = getConfig.getInstanceIdentifierFromDocument(request); + assertTrue(iid.equals(identifier)); + } + + private class TestingGetConfig extends GetConfig{ + public TestingGetConfig(String sessionId, CurrentSchemaContext schemaContext, TransactionProvider transactionProvider) { + super(sessionId, schemaContext, transactionProvider); + } + + public YangInstanceIdentifier getInstanceIdentifierFromDocument(Document request) throws DocumentedException { + XmlElement filterElement = XmlElement.fromDomDocument(request).getOnlyChildElement(GET_CONFIG).getOnlyChildElement(FILTER_NODE); + return getInstanceIdentifierFromFilter(filterElement); + } + } + private void deleteDatastore() throws Exception{ - verifyResponse(edit("messages/mapping/editConfig_delete-root.xml"), RPC_REPLY_OK); + verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-root.xml"), RPC_REPLY_OK); assertEmptyDatastore(getConfigCandidate()); verifyResponse(commit(), RPC_REPLY_OK); assertEmptyDatastore(getConfigRunning()); } - private void verifyResponse(Document response, Document template) { + private void verifyResponse(Document response, Document template) throws IOException, TransformerException { DetailedDiff dd = new DetailedDiff(new Diff(response, template)); - dd.overrideElementQualifier(new RecursiveElementNameAndTextQualifier()); - assertTrue(dd.similar()); + dd.overrideElementQualifier(new NetconfXmlUnitRecursiveQualifier()); + + printDocument(response); + printDocument(template); + + assertTrue(dd.toString(), dd.similar()); } private void assertEmptyDatastore(Document response) { @@ -309,7 +539,7 @@ public class NetconfMDSalMappingTest { NodeList nodes = response.getChildNodes(); assertTrue(nodes.getLength() == 1); - assertEquals(nodes.item(0).getLocalName(),RPC_REPLY_ELEMENT); + assertEquals(nodes.item(0).getLocalName(), RPC_REPLY_ELEMENT); NodeList replyNodes = nodes.item(0).getChildNodes(); assertTrue(replyNodes.getLength() == 1); @@ -320,66 +550,81 @@ public class NetconfMDSalMappingTest { } - private Document commit() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document commit() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Commit commit = new Commit(sessionIdForReporting, transactionProvider); return executeOperation(commit, "messages/mapping/commit.xml"); } - private Document discardChanges() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document discardChanges() throws DocumentedException, ParserConfigurationException, SAXException, IOException { DiscardChanges discardOp = new DiscardChanges(sessionIdForReporting, transactionProvider); return executeOperation(discardOp, "messages/mapping/discardChanges.xml"); } - private Document edit(String resource) throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document edit(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException { EditConfig editConfig = new EditConfig(sessionIdForReporting, currentSchemaContext, transactionProvider); return executeOperation(editConfig, resource); } - private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document get() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider); return executeOperation(get, "messages/mapping/get.xml"); } - private Document getConfigRunning() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document getWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException { + Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider); + return executeOperation(get, resource); + } + + private Document getConfigRunning() throws DocumentedException, ParserConfigurationException, SAXException, IOException { GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider); return executeOperation(getConfig, "messages/mapping/getConfig.xml"); } - private Document getConfigCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document getConfigCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException { GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider); return executeOperation(getConfig, "messages/mapping/getConfig_candidate.xml"); } - private Document lock() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document getConfigWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException { + GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider); + return executeOperation(getConfig, resource); + } + + private Document lock() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Lock lock = new Lock(sessionIdForReporting); return executeOperation(lock, "messages/mapping/lock.xml"); } - private Document unlock() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document unlock() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Unlock unlock = new Unlock(sessionIdForReporting); return executeOperation(unlock, "messages/mapping/unlock.xml"); } - private Document lockCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document lockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException { + Lock lock = new Lock(sessionIdForReporting); + return executeOperation(lock, "messages/mapping/lock_notarget.xml"); + } + + private Document unlockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException { + Unlock unlock = new Unlock(sessionIdForReporting); + return executeOperation(unlock, "messages/mapping/unlock_notarget.xml"); + } + + private Document lockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Lock lock = new Lock(sessionIdForReporting); return executeOperation(lock, "messages/mapping/lock_candidate.xml"); } - private Document unlockCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { + private Document unlockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException { Unlock unlock = new Unlock(sessionIdForReporting); return executeOperation(unlock, "messages/mapping/unlock_candidate.xml"); } - private Document executeOperation(NetconfOperation op, String filename) throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException { + private Document executeOperation(NetconfOperation op, String filename) throws ParserConfigurationException, SAXException, IOException, DocumentedException { final Document request = XmlFileLoader.xmlFileToDocument(filename); - - HandlingPriority priority = op.canHandle(request); - Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE); - final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT); LOG.debug("Got response {}" , response); - return response; }