Eliminate PatchDataTransactionUtilTest 07/107207/2
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 1 Aug 2023 22:23:22 +0000 (00:23 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 2 Aug 2023 09:55:36 +0000 (11:55 +0200)
Integrate tests into AbstractRestconfStrategyTest to bring them closer
to where we want the logic to execute.

JIRA: NETCONF-1107
Change-Id: Ia3860063264be30e5e92b15e976c1ee6240330cd
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/AbstractRestconfStrategyTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/MdsalRestconfStrategyTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/NetconfRestconfStrategyTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PatchDataTransactionUtilTest.java [deleted file]

index d791b4418909e5d9e2c000f0b80faf418eddd4fb..89ea8d0e71fc2a659304d7038e3ca2acdcab5008 100644 (file)
@@ -10,21 +10,34 @@ package org.opendaylight.restconf.nb.rfc8040.rests.transactions;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
+import static org.opendaylight.restconf.common.patch.PatchEditOperation.CREATE;
+import static org.opendaylight.restconf.common.patch.PatchEditOperation.DELETE;
+import static org.opendaylight.restconf.common.patch.PatchEditOperation.MERGE;
+import static org.opendaylight.restconf.common.patch.PatchEditOperation.REMOVE;
+import static org.opendaylight.restconf.common.patch.PatchEditOperation.REPLACE;
 
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import org.eclipse.jdt.annotation.NonNull;
 import org.junit.Test;
 import org.mockito.Mock;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.patch.PatchContext;
+import org.opendaylight.restconf.common.patch.PatchEntity;
+import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.nb.rfc8040.AbstractJukeboxTest;
 import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
 import org.opendaylight.restconf.nb.rfc8040.rests.utils.DeleteDataTransactionUtil;
+import org.opendaylight.restconf.nb.rfc8040.rests.utils.PatchDataTransactionUtil;
 import org.opendaylight.restconf.nb.rfc8040.rests.utils.PlainPatchDataTransactionUtil;
 import org.opendaylight.restconf.nb.rfc8040.rests.utils.PostDataTransactionUtil;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
@@ -77,6 +90,16 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
             .build())
         .build();
     static final YangInstanceIdentifier PLAYLIST_IID = YangInstanceIdentifier.of(JUKEBOX_QNAME, PLAYLIST_QNAME);
+    // instance identifier for accessing container node "player"
+    static final YangInstanceIdentifier PLAYER_IID = YangInstanceIdentifier.of(JUKEBOX_QNAME, PLAYER_QNAME);
+    static final YangInstanceIdentifier ARTIST_IID = YangInstanceIdentifier.builder()
+        .node(JUKEBOX_QNAME)
+        .node(LIBRARY_QNAME)
+        .node(ARTIST_QNAME)
+        .nodeWithKey(ARTIST_QNAME, NAME_QNAME, "name of artist")
+        .build();
+    // FIXME: this looks weird
+    static final YangInstanceIdentifier CREATE_AND_DELETE_TARGET = GAP_IID.node(PLAYER_QNAME).node(GAP_QNAME);
 
     @Mock
     private UriInfo uriInfo;
@@ -177,4 +200,70 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
     }
 
     abstract @NonNull RestconfStrategy testPatchListDataStrategy();
+
+    @Test
+    public final void testPatchDataReplaceMergeAndRemove() {
+        final var buildArtistList = Builders.mapBuilder()
+            .withNodeIdentifier(new NodeIdentifier(ARTIST_QNAME))
+            .withChild(Builders.mapEntryBuilder()
+                .withNodeIdentifier(NodeIdentifierWithPredicates.of(ARTIST_QNAME, NAME_QNAME, "name of artist"))
+                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "name of artist"))
+                .withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, "description of artist"))
+                .build())
+            .build();
+
+        patch(new PatchContext(
+            InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, ARTIST_IID.node(NAME_QNAME)),
+            List.of(new PatchEntity("edit1", REPLACE, ARTIST_IID, buildArtistList),
+                new PatchEntity("edit2", MERGE, ARTIST_IID, buildArtistList),
+                new PatchEntity("edit3", REMOVE, ARTIST_IID)),
+            "patchRMRm"), testPatchDataReplaceMergeAndRemoveStrategy(), false);
+    }
+
+    abstract @NonNull RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy();
+
+    @Test
+    public final void testPatchDataCreateAndDelete() {
+        patch(new PatchContext(InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
+            List.of(new PatchEntity("edit1", CREATE, PLAYER_IID, EMPTY_JUKEBOX),
+                new PatchEntity("edit2", DELETE, CREATE_AND_DELETE_TARGET)),
+            "patchCD"),
+            testPatchDataCreateAndDeleteStrategy(), true);
+    }
+
+    abstract @NonNull RestconfStrategy testPatchDataCreateAndDeleteStrategy();
+
+    @Test
+    public final void testPatchMergePutContainer() {
+        patch(new PatchContext(InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
+            List.of(new PatchEntity("edit1", MERGE, PLAYER_IID, EMPTY_JUKEBOX)), "patchM"),
+            testPatchMergePutContainerStrategy(), false);
+    }
+
+    abstract @NonNull RestconfStrategy testPatchMergePutContainerStrategy();
+
+    @Test
+    public final void testDeleteNonexistentData() {
+        final var patchStatusContext = PatchDataTransactionUtil.patchData(new PatchContext(
+            InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
+            List.of(new PatchEntity("edit", DELETE, CREATE_AND_DELETE_TARGET)), "patchD"),
+            deleteNonexistentDataTestStrategy(), JUKEBOX_SCHEMA);
+        assertFalse(patchStatusContext.isOk());
+    }
+
+    abstract @NonNull RestconfStrategy deleteNonexistentDataTestStrategy();
+
+    abstract void assertTestDeleteNonexistentData(@NonNull PatchStatusContext status);
+
+    private static void patch(final PatchContext patchContext, final RestconfStrategy strategy, final boolean failed) {
+        final var patchStatusContext = PatchDataTransactionUtil.patchData(patchContext, strategy, JUKEBOX_SCHEMA);
+        for (var entity : patchStatusContext.getEditCollection()) {
+            if (failed) {
+                assertTrue("Edit " + entity.getEditId() + " failed", entity.isOk());
+            } else {
+                assertTrue(entity.isOk());
+            }
+        }
+        assertTrue(patchStatusContext.isOk());
+    }
 }
index faa61be9a8922cc432f6b986cbd52aa71fe93388..21396c3a4bf27c275831ba34d2603cbc8ff0d153 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.rests.transactions;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
@@ -25,8 +26,11 @@ import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
 import org.opendaylight.restconf.nb.rfc8040.rests.utils.PutDataTransactionUtil;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.w3c.dom.DOMException;
@@ -149,4 +153,40 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
         return new MdsalRestconfStrategy(mockDataBroker);
     }
+
+    @Override
+    RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
+        return new MdsalRestconfStrategy(mockDataBroker);
+    }
+
+    @Override
+    RestconfStrategy testPatchDataCreateAndDeleteStrategy() {
+        doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, PLAYER_IID);
+        doReturn(immediateTrueFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
+            CREATE_AND_DELETE_TARGET);
+        return new MdsalRestconfStrategy(mockDataBroker);
+    }
+
+    @Override
+    RestconfStrategy testPatchMergePutContainerStrategy() {
+        return new MdsalRestconfStrategy(mockDataBroker);
+    }
+
+    @Override
+    RestconfStrategy deleteNonexistentDataTestStrategy() {
+        doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
+            CREATE_AND_DELETE_TARGET);
+        return new MdsalRestconfStrategy(mockDataBroker);
+    }
+
+    @Override
+    void assertTestDeleteNonexistentData(final PatchStatusContext status) {
+        final var editCollection = status.getEditCollection();
+        assertEquals(1, editCollection.size());
+        final var editErrors = editCollection.get(0).getEditErrors();
+        assertEquals(1, editErrors.size());
+        final var editError = editErrors.get(0);
+        assertEquals(ErrorType.PROTOCOL, editError.getErrorType());
+        assertEquals(ErrorTag.DATA_MISSING, editError.getErrorTag());
+    }
 }
index 073f6a629ad5c5e2d71f204264aa18bea7f3d73e..2e936ee764474d6541c58ce127b1e336afa40de2 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.rests.transactions;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -26,6 +27,7 @@ import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.netconf.api.NetconfDocumentedException;
 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
+import org.opendaylight.restconf.common.patch.PatchStatusContext;
 import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
 import org.opendaylight.restconf.nb.rfc8040.rests.utils.PutDataTransactionUtil;
 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
@@ -49,6 +51,8 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of());
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),
+            any(), any());
     }
 
     @Override
@@ -199,4 +203,47 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
             Optional.empty());
     }
+
+    @Override
+    RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            .remove(LogicalDatastoreType.CONFIGURATION, ARTIST_IID);
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            .replace(any(), any(), any(), any());
+        return new NetconfRestconfStrategy(netconfService);
+    }
+
+    @Override
+    RestconfStrategy testPatchDataCreateAndDeleteStrategy() {
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            .create(LogicalDatastoreType.CONFIGURATION, PLAYER_IID, EMPTY_JUKEBOX, Optional.empty());
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
+        return new NetconfRestconfStrategy(netconfService);
+    }
+
+    @Override
+    RestconfStrategy testPatchMergePutContainerStrategy() {
+        return new NetconfRestconfStrategy(netconfService);
+    }
+
+    @Override
+    RestconfStrategy deleteNonexistentDataTestStrategy() {
+        doReturn(Futures.immediateFailedFuture(
+            new TransactionCommitFailedException("Commit of transaction " + this + " failed",
+                new NetconfDocumentedException("id", ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR))))
+            .when(netconfService).commit();
+        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
+        return new NetconfRestconfStrategy(netconfService);
+    }
+
+    @Override
+    void assertTestDeleteNonexistentData(final PatchStatusContext status) {
+        final var globalErrors = status.getGlobalErrors();
+        assertEquals(1, globalErrors.size());
+        final var globalError = globalErrors.get(0);
+        assertEquals(ErrorType.PROTOCOL, globalError.getErrorType());
+        assertEquals(ErrorTag.DATA_MISSING, globalError.getErrorTag());
+    }
 }
diff --git a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PatchDataTransactionUtilTest.java b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PatchDataTransactionUtilTest.java
deleted file mode 100644 (file)
index b9d775e..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2016 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.restconf.nb.rfc8040.rests.utils;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.opendaylight.restconf.common.patch.PatchEditOperation.CREATE;
-import static org.opendaylight.restconf.common.patch.PatchEditOperation.DELETE;
-import static org.opendaylight.restconf.common.patch.PatchEditOperation.MERGE;
-import static org.opendaylight.restconf.common.patch.PatchEditOperation.REMOVE;
-import static org.opendaylight.restconf.common.patch.PatchEditOperation.REPLACE;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
-import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
-
-import com.google.common.util.concurrent.Futures;
-import java.util.List;
-import java.util.Optional;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.api.NetconfDocumentedException;
-import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
-import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.common.patch.PatchEntity;
-import org.opendaylight.restconf.nb.rfc8040.AbstractJukeboxTest;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
-import org.opendaylight.yangtools.yang.common.ErrorSeverity;
-import org.opendaylight.yangtools.yang.common.ErrorTag;
-import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class PatchDataTransactionUtilTest extends AbstractJukeboxTest {
-    // instance identifier for accessing container node "player"
-    private static final YangInstanceIdentifier PLAYER_IID = YangInstanceIdentifier.of(JUKEBOX_QNAME, PLAYER_QNAME);
-    private static final YangInstanceIdentifier ARTIST_IID = YangInstanceIdentifier.builder()
-        .node(JUKEBOX_QNAME)
-        .node(LIBRARY_QNAME)
-        .node(ARTIST_QNAME)
-        .nodeWithKey(ARTIST_QNAME, NAME_QNAME, "name of artist")
-        .build();
-    // FIXME: this looks weird
-    private static final YangInstanceIdentifier CREATE_AND_DELETE_TARGET = GAP_IID.node(PLAYER_QNAME).node(GAP_QNAME);
-
-    @Mock
-    private DOMDataTreeReadWriteTransaction rwTransaction;
-    @Mock
-    private DOMDataBroker mockDataBroker;
-    @Mock
-    private NetconfDataTreeService netconfService;
-
-    @Before
-    public void before() {
-        doReturn(rwTransaction).when(mockDataBroker).newReadWriteTransaction();
-        doReturn(CommitInfo.emptyFluentFuture()).when(rwTransaction).commit();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),
-            any(), any());
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).replace(any(), any(),
-            any(), any());
-    }
-
-    @Test
-    public void testPatchDataReplaceMergeAndRemove() {
-        final var buildArtistList = Builders.mapBuilder()
-            .withNodeIdentifier(new NodeIdentifier(ARTIST_QNAME))
-            .withChild(Builders.mapEntryBuilder()
-                .withNodeIdentifier(NodeIdentifierWithPredicates.of(ARTIST_QNAME, NAME_QNAME, "name of artist"))
-                .withChild(ImmutableNodes.leafNode(NAME_QNAME, "name of artist"))
-                .withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, "description of artist"))
-                .build())
-            .build();
-
-        final var patchContext = new PatchContext(
-            InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, ARTIST_IID.node(NAME_QNAME)),
-            List.of(new PatchEntity("edit1", REPLACE, ARTIST_IID, buildArtistList),
-                new PatchEntity("edit2", MERGE, ARTIST_IID, buildArtistList),
-                new PatchEntity("edit3", REMOVE, ARTIST_IID)),
-            "patchRMRm");
-
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
-            .remove(LogicalDatastoreType.CONFIGURATION, ARTIST_IID);
-
-        patch(patchContext, new MdsalRestconfStrategy(mockDataBroker), false);
-        patch(patchContext, new NetconfRestconfStrategy(netconfService), false);
-    }
-
-    @Test
-    public void testPatchDataCreateAndDelete() {
-        doReturn(immediateFalseFluentFuture()).when(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION,
-            PLAYER_IID);
-        doReturn(immediateTrueFluentFuture()).when(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION,
-            CREATE_AND_DELETE_TARGET);
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
-            .create(LogicalDatastoreType.CONFIGURATION, PLAYER_IID, EMPTY_JUKEBOX, Optional.empty());
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
-            .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
-
-        final var patchContext = new PatchContext(InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
-            List.of(new PatchEntity("edit1", CREATE, PLAYER_IID, EMPTY_JUKEBOX),
-                new PatchEntity("edit2", DELETE, CREATE_AND_DELETE_TARGET)),
-            "patchCD");
-        patch(patchContext, new MdsalRestconfStrategy(mockDataBroker), true);
-        patch(patchContext, new NetconfRestconfStrategy(netconfService), true);
-    }
-
-    @Test
-    public void deleteNonexistentDataTest() {
-        doReturn(immediateFalseFluentFuture()).when(rwTransaction).exists(LogicalDatastoreType.CONFIGURATION,
-            CREATE_AND_DELETE_TARGET);
-        doReturn(Futures.immediateFailedFuture(
-            new TransactionCommitFailedException("Commit of transaction " + this + " failed",
-                new NetconfDocumentedException("id", ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR))))
-            .when(netconfService).commit();
-        doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
-            .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
-
-        final var patchContext = new PatchContext(InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
-            List.of(new PatchEntity("edit", DELETE, CREATE_AND_DELETE_TARGET)), "patchD");
-        deleteMdsal(patchContext, new MdsalRestconfStrategy(mockDataBroker));
-        deleteNetconf(patchContext, new NetconfRestconfStrategy(netconfService));
-    }
-
-    @Test
-    public void testPatchMergePutContainer() {
-        final var patchContext = new PatchContext(InstanceIdentifierContext.ofLocalPath(JUKEBOX_SCHEMA, GAP_IID),
-            List.of(new PatchEntity("edit1", MERGE, PLAYER_IID, EMPTY_JUKEBOX)), "patchM");
-        patch(patchContext, new MdsalRestconfStrategy(mockDataBroker), false);
-        patch(patchContext, new NetconfRestconfStrategy(netconfService), false);
-    }
-
-    private static void patch(final PatchContext patchContext, final RestconfStrategy strategy, final boolean failed) {
-        final var patchStatusContext = PatchDataTransactionUtil.patchData(patchContext, strategy, JUKEBOX_SCHEMA);
-        for (var entity : patchStatusContext.getEditCollection()) {
-            if (failed) {
-                assertTrue("Edit " + entity.getEditId() + " failed", entity.isOk());
-            } else {
-                assertTrue(entity.isOk());
-            }
-        }
-        assertTrue(patchStatusContext.isOk());
-    }
-
-    private static void deleteMdsal(final PatchContext patchContext, final RestconfStrategy strategy) {
-        final var patchStatusContext = PatchDataTransactionUtil.patchData(patchContext, strategy, JUKEBOX_SCHEMA);
-        assertFalse(patchStatusContext.isOk());
-
-        final var editCollection = patchStatusContext.getEditCollection();
-        assertEquals(1, editCollection.size());
-        final var editErrors = patchStatusContext.getEditCollection().get(0).getEditErrors();
-        assertEquals(1, editErrors.size());
-        final var editError = editErrors.get(0);
-        assertEquals(ErrorType.PROTOCOL, editError.getErrorType());
-        assertEquals(ErrorTag.DATA_MISSING, editError.getErrorTag());
-    }
-
-    private static void deleteNetconf(final PatchContext patchContext, final RestconfStrategy strategy) {
-        final var patchStatusContext = PatchDataTransactionUtil.patchData(patchContext, strategy, JUKEBOX_SCHEMA);
-        assertFalse(patchStatusContext.isOk());
-        final var globalErrors = patchStatusContext.getGlobalErrors();
-        assertEquals(1, globalErrors.size());
-        final var globalError = globalErrors.get(0);
-        assertEquals(ErrorType.PROTOCOL, globalError.getErrorType());
-        assertEquals(ErrorTag.DATA_MISSING, globalError.getErrorTag());
-    }
-}