Further rework of base schemas
[netconf.git] / netconf / netconf-topology-singleton / src / test / java / org / opendaylight / netconf / topology / singleton / impl / NetconfNodeActorTest.java
index 09415d9c67fcf16d0b03f0efdc14f9601a12fa92..d168478b8850150ecd6b3178892552138e8143f7 100644 (file)
@@ -5,16 +5,16 @@
  * 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.netconf.topology.singleton.impl;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.after;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
@@ -45,6 +45,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.SettableFuture;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Scanner;
@@ -56,22 +57,29 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSourceSerializationProxy;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMActionException;
+import org.opendaylight.mdsal.dom.api.DOMActionResult;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMNotificationService;
+import org.opendaylight.mdsal.dom.api.DOMRpcException;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.SchemaResourcesDTO;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringActionException;
 import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringRpcException;
 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
 import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup.NetconfTopologySetupBuilder;
@@ -83,21 +91,23 @@ import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterAc
 import org.opendaylight.netconf.topology.singleton.messages.RegisterMountPoint;
 import org.opendaylight.netconf.topology.singleton.messages.UnregisterSlaveMountPoint;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory;
 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
@@ -109,7 +119,7 @@ import scala.concurrent.Await;
 import scala.concurrent.Future;
 import scala.concurrent.duration.Duration;
 
-public class NetconfNodeActorTest {
+public class NetconfNodeActorTest extends AbstractBaseSchemasTest {
 
     private static final Timeout TIMEOUT = new Timeout(Duration.create(5, "seconds"));
     private static final RevisionSourceIdentifier SOURCE_IDENTIFIER1 = RevisionSourceIdentifier.create("yang1");
@@ -128,6 +138,9 @@ public class NetconfNodeActorTest {
     @Mock
     private DOMRpcService mockDOMRpcService;
 
+    @Mock
+    private DOMActionService mockDOMActionService;
+
     @Mock
     private DOMMountPointService mockMountPointService;
 
@@ -150,13 +163,16 @@ public class NetconfNodeActorTest {
     private SchemaSourceRegistry mockRegistry;
 
     @Mock
-    private SchemaContextFactory mockSchemaContextFactory;
+    private EffectiveModelContextFactory mockSchemaContextFactory;
 
     @Mock
     private SchemaRepository mockSchemaRepository;
 
     @Mock
-    private SchemaContext mockSchemaContext;
+    private EffectiveModelContext mockSchemaContext;
+
+    @Mock
+    private SchemaResourcesDTO schemaResourceDTO;
 
     @Before
     public void setup() {
@@ -168,11 +184,13 @@ public class NetconfNodeActorTest {
         masterSchemaRepository.registerSchemaSourceListener(
                 TextToASTTransformer.create(masterSchemaRepository, masterSchemaRepository));
 
+        doReturn(masterSchemaRepository).when(schemaResourceDTO).getSchemaRepository();
+        doReturn(mockRegistry).when(schemaResourceDTO).getSchemaRegistry();
         final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system)
-                .setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS)).build();
+                .setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS)).setSchemaResourceDTO(schemaResourceDTO)
+                .setBaseSchemas(BASE_SCHEMAS).build();
 
-        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, masterSchemaRepository,
-                masterSchemaRepository, TIMEOUT, mockMountPointService);
+        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
 
         masterRef = TestActorRef.create(system, props, "master_messages");
 
@@ -184,12 +202,12 @@ public class NetconfNodeActorTest {
         doReturn(mockSchemaSourceReg2).when(mockRegistry).registerSchemaSource(any(), withSourceId(SOURCE_IDENTIFIER2));
 
         doReturn(mockSchemaContextFactory).when(mockSchemaRepository)
-                .createSchemaContextFactory(any(SchemaSourceFilter.class));
+                .createEffectiveModelContextFactory();
     }
 
     @After
     public void teardown() {
-        TestKit.shutdownActorSystem(system, Boolean.TRUE);
+        TestKit.shutdownActorSystem(system, true);
         system = null;
     }
 
@@ -198,14 +216,15 @@ public class NetconfNodeActorTest {
 
         // Test CreateInitialMasterActorData.
 
-        initializeMaster(Lists.newArrayList());
+        initializeMaster(new ArrayList<>());
 
         // Test RefreshSetupMasterActorData.
 
         final RemoteDeviceId newRemoteDeviceId = new RemoteDeviceId("netconf-topology2",
                 new InetSocketAddress(InetAddresses.forString("127.0.0.2"), 9999));
 
-        final NetconfTopologySetup newSetup = NetconfTopologySetupBuilder.create().setActorSystem(system).build();
+        final NetconfTopologySetup newSetup = NetconfTopologySetupBuilder.create().setBaseSchemas(BASE_SCHEMAS)
+                .setSchemaResourceDTO(schemaResourceDTO).setActorSystem(system).build();
 
         masterRef.tell(new RefreshSetupMasterActorData(newSetup, newRemoteDeviceId), testKit.getRef());
 
@@ -213,7 +232,7 @@ public class NetconfNodeActorTest {
     }
 
     @Test
-    public void tesAskForMasterMountPoint() {
+    public void testAskForMasterMountPoint() {
 
         // Test with master not setup yet.
 
@@ -258,13 +277,13 @@ public class NetconfNodeActorTest {
         doReturn(mockSchemaSourceReg1).when(mockRegistry).registerSchemaSource(any(), withSourceId(SOURCE_IDENTIFIER1));
 
         doReturn(mockSchemaContextFactory).when(mockSchemaRepository)
-                .createSchemaContextFactory(any(SchemaSourceFilter.class));
+                .createEffectiveModelContextFactory();
 
         final SchemaSourceRegistration<?> newMockSchemaSourceReg = mock(SchemaSourceRegistration.class);
 
-        final SchemaContextFactory newMockSchemaContextFactory = mock(SchemaContextFactory.class);
+        final EffectiveModelContextFactory newMockSchemaContextFactory = mock(EffectiveModelContextFactory.class);
         doReturn(Futures.immediateFuture(mockSchemaContext))
-                .when(newMockSchemaContextFactory).createSchemaContext(any());
+                .when(newMockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
         doAnswer(unused -> {
             SettableFuture<SchemaContext> future = SettableFuture.create();
@@ -273,7 +292,7 @@ public class NetconfNodeActorTest {
                         withSourceId(SOURCE_IDENTIFIER1));
 
                 doReturn(newMockSchemaContextFactory).when(mockSchemaRepository)
-                        .createSchemaContextFactory(any(SchemaSourceFilter.class));
+                        .createEffectiveModelContextFactory();
 
                 slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1), masterRef),
                         testKit.getRef());
@@ -281,10 +300,10 @@ public class NetconfNodeActorTest {
                 future.set(mockSchemaContext);
             }).start();
             return future;
-        }).when(mockSchemaContextFactory).createSchemaContext(any());
+        }).when(mockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
         doReturn(mockSchemaContextFactory).when(mockSchemaRepository)
-                .createSchemaContextFactory(any(SchemaSourceFilter.class));
+                .createEffectiveModelContextFactory();
 
         slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1), masterRef), testKit.getRef());
 
@@ -292,10 +311,11 @@ public class NetconfNodeActorTest {
         verify(mockMountPointBuilder, after(500)).addInitialSchemaContext(mockSchemaContext);
         verify(mockMountPointBuilder).addService(eq(DOMDataBroker.class), any());
         verify(mockMountPointBuilder).addService(eq(DOMRpcService.class), any());
+        verify(mockMountPointBuilder).addService(eq(DOMActionService.class), any());
         verify(mockMountPointBuilder).addService(eq(DOMNotificationService.class), any());
         verify(mockSchemaSourceReg1).close();
         verify(mockRegistry, times(2)).registerSchemaSource(any(), withSourceId(SOURCE_IDENTIFIER1));
-        verify(mockSchemaRepository, times(2)).createSchemaContextFactory(any(SchemaSourceFilter.class));
+        verify(mockSchemaRepository, times(2)).createEffectiveModelContextFactory();
         verifyNoMoreInteractions(mockMountPointBuilder, newMockSchemaSourceReg);
 
         // Stop the slave actor and verify schema source registrations are closed.
@@ -310,15 +330,22 @@ public class NetconfNodeActorTest {
     @SuppressWarnings("unchecked")
     @Test
     public void testRegisterMountPointWithSchemaFailures() throws Exception {
-        final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system).build();
-
-        final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, mockRegistry,
-                mockSchemaRepository, TIMEOUT, mockMountPointService));
+        SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class);
+        doReturn(mockRegistry).when(schemaResourceDTO2).getSchemaRegistry();
+        doReturn(mockSchemaRepository).when(schemaResourceDTO2).getSchemaRepository();
+        final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create()
+                .setSchemaResourceDTO(schemaResourceDTO2)
+                .setBaseSchemas(BASE_SCHEMAS)
+                .setActorSystem(system)
+                .build();
+
+        final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT,
+                mockMountPointService));
 
         // Test unrecoverable failure.
 
         doReturn(Futures.immediateFailedFuture(new SchemaResolutionException("mock")))
-                .when(mockSchemaContextFactory).createSchemaContext(any());
+                .when(mockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
         slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1, SOURCE_IDENTIFIER2),
                 masterRef), testKit.getRef());
@@ -339,7 +366,7 @@ public class NetconfNodeActorTest {
         doReturn(Futures.immediateFailedFuture(new SchemaResolutionException("mock",
                 new AskTimeoutException("timeout"))))
             .doReturn(Futures.immediateFuture(mockSchemaContext))
-            .when(mockSchemaContextFactory).createSchemaContext(any());
+            .when(mockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
         slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1, SOURCE_IDENTIFIER2),
                 masterRef), testKit.getRef());
@@ -355,15 +382,15 @@ public class NetconfNodeActorTest {
         reset(mockSchemaSourceReg1, mockSchemaSourceReg2, mockSchemaRepository, mockSchemaContextFactory);
         resetMountPointMocks();
 
-        final SchemaContextFactory mockSchemaContextFactorySuccess = mock(SchemaContextFactory.class);
+        final EffectiveModelContextFactory mockSchemaContextFactorySuccess = mock(EffectiveModelContextFactory.class);
         doReturn(Futures.immediateFuture(mockSchemaContext))
-                .when(mockSchemaContextFactorySuccess).createSchemaContext(any());
+                .when(mockSchemaContextFactorySuccess).createEffectiveModelContext(anyCollection());
 
         doAnswer(unused -> {
             SettableFuture<SchemaContext> future = SettableFuture.create();
             new Thread(() -> {
                 doReturn(mockSchemaContextFactorySuccess).when(mockSchemaRepository)
-                        .createSchemaContextFactory(any(SchemaSourceFilter.class));
+                    .createEffectiveModelContextFactory();
 
                 slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1, SOURCE_IDENTIFIER2),
                         masterRef), testKit.getRef());
@@ -371,16 +398,38 @@ public class NetconfNodeActorTest {
                 future.setException(new SchemaResolutionException("mock", new AskTimeoutException("timeout")));
             }).start();
             return future;
-        }).when(mockSchemaContextFactory).createSchemaContext(any());
+        }).when(mockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
-        doReturn(mockSchemaContextFactory).when(mockSchemaRepository)
-                .createSchemaContextFactory(any(SchemaSourceFilter.class));
+        doReturn(mockSchemaContextFactory).when(mockSchemaRepository).createEffectiveModelContextFactory();
 
         slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1, SOURCE_IDENTIFIER2),
                 masterRef), testKit.getRef());
 
         verify(mockMountPointBuilder, timeout(5000)).register();
-        verify(mockSchemaRepository, times(2)).createSchemaContextFactory(any(SchemaSourceFilter.class));
+        verify(mockSchemaRepository, times(2)).createEffectiveModelContextFactory();
+    }
+
+    @Test(expected = MissingSchemaSourceException.class)
+    public void testMissingSchemaSourceOnMissingProvider() throws Exception {
+        final SharedSchemaRepository repository = new SharedSchemaRepository("test");
+
+        SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class);
+        doReturn(repository).when(schemaResourceDTO2).getSchemaRegistry();
+        doReturn(repository).when(schemaResourceDTO2).getSchemaRepository();
+        final NetconfTopologySetup setup = NetconfTopologySetupBuilder.create().setActorSystem(system)
+                .setSchemaResourceDTO(schemaResourceDTO2).setIdleTimeout(Duration.apply(1, TimeUnit.SECONDS))
+                .setBaseSchemas(BASE_SCHEMAS).build();
+        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, TIMEOUT, mockMountPointService);
+        ActorRef actor = TestActorRef.create(system, props, "master_messages_2");
+
+        final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("testID");
+
+        final ProxyYangTextSourceProvider proxyYangProvider =
+                new ProxyYangTextSourceProvider(actor, system.dispatcher(), TIMEOUT);
+
+        final Future<YangTextSchemaSourceSerializationProxy> resolvedSchemaFuture =
+                proxyYangProvider.getYangTextSchemaSource(sourceIdentifier);
+        Await.result(resolvedSchemaFuture, TIMEOUT.duration());
     }
 
     @Test
@@ -444,7 +493,7 @@ public class NetconfNodeActorTest {
 
         // RPC with no response output.
 
-        doReturn(Futures.immediateCheckedFuture(null)).when(mockDOMRpcService).invokeRpc(any(), any());
+        doReturn(FluentFutures.immediateNullFluentFuture()).when(mockDOMRpcService).invokeRpc(any(), any());
 
         DOMRpcResult result = slaveDomRPCService.invokeRpc(schemaPath, outputNode).get(2, TimeUnit.SECONDS);
 
@@ -452,7 +501,7 @@ public class NetconfNodeActorTest {
 
         // RPC with response output.
 
-        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(outputNode)))
+        doReturn(FluentFutures.immediateFluentFuture(new DefaultDOMRpcResult(outputNode)))
                 .when(mockDOMRpcService).invokeRpc(any(), any());
 
         result = slaveDomRPCService.invokeRpc(schemaPath, outputNode).get(2, TimeUnit.SECONDS);
@@ -462,7 +511,7 @@ public class NetconfNodeActorTest {
 
         // RPC with response error.
 
-        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(rpcError)))
+        doReturn(FluentFutures.immediateFluentFuture(new DefaultDOMRpcResult(rpcError)))
                 .when(mockDOMRpcService).invokeRpc(any(), any());
 
         result = slaveDomRPCService.invokeRpc(schemaPath, outputNode).get(2, TimeUnit.SECONDS);
@@ -472,7 +521,7 @@ public class NetconfNodeActorTest {
 
         // RPC with response output and error.
 
-        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(outputNode, rpcError)))
+        doReturn(FluentFutures.immediateFluentFuture(new DefaultDOMRpcResult(outputNode, rpcError)))
                 .when(mockDOMRpcService).invokeRpc(any(), any());
 
         final DOMRpcResult resultOutputError =
@@ -485,7 +534,7 @@ public class NetconfNodeActorTest {
 
         exception.expect(DOMRpcException.class);
 
-        doReturn(Futures.immediateFailedCheckedFuture(new ClusteringRpcException("mock")))
+        doReturn(FluentFutures.immediateFailedFluentFuture(new ClusteringRpcException("mock")))
                 .when(mockDOMRpcService).invokeRpc(any(), any());
 
         try {
@@ -495,12 +544,66 @@ public class NetconfNodeActorTest {
         }
     }
 
+    @Test
+    @SuppressWarnings({"checkstyle:AvoidHidingCauseException", "checkstyle:IllegalThrows"})
+    public void testSlaveInvokeAction() throws Throwable {
+        final List<SourceIdentifier> sourceIdentifiers = Lists
+            .newArrayList(RevisionSourceIdentifier.create("testActionID"));
+        initializeMaster(sourceIdentifiers);
+        registerSlaveMountPoint();
+
+        ArgumentCaptor<DOMActionService> domActionServiceCaptor = ArgumentCaptor.forClass(DOMActionService.class);
+        verify(mockMountPointBuilder).addService(eq(DOMActionService.class), domActionServiceCaptor.capture());
+
+        final DOMActionService slaveDomActionService = domActionServiceCaptor.getValue();
+        assertTrue(slaveDomActionService instanceof ProxyDOMActionService);
+
+        final QName testQName = QName.create("test", "2019-08-16", "TestActionQname");
+        final SchemaPath schemaPath = SchemaPath.create(true, testQName);
+
+        final YangInstanceIdentifier yangIIdPath = YangInstanceIdentifier
+            .create(new YangInstanceIdentifier.NodeIdentifier(testQName));
+
+        final DOMDataTreeIdentifier domDataTreeIdentifier = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
+            yangIIdPath);
+
+        final ContainerNode outputNode = ImmutableContainerNodeBuilder.create()
+            .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(testQName))
+            .withChild(ImmutableNodes.leafNode(testQName, "foo")).build();
+
+        // Action with no response output.
+        doReturn(FluentFutures.immediateNullFluentFuture()).when(mockDOMActionService)
+            .invokeAction(any(), any(), any());
+        DOMActionResult result = slaveDomActionService.invokeAction(schemaPath, domDataTreeIdentifier, outputNode)
+            .get(2, TimeUnit.SECONDS);
+        assertEquals(null, result);
+
+        // Action with response output.
+        doReturn(FluentFutures.immediateFluentFuture(new SimpleDOMActionResult(outputNode))).when(mockDOMActionService)
+            .invokeAction(any(), any(), any());
+        result = slaveDomActionService.invokeAction(schemaPath, domDataTreeIdentifier, outputNode)
+            .get(2, TimeUnit.SECONDS);
+
+        assertEquals(outputNode, result.getOutput().get());
+        assertTrue(result.getErrors().isEmpty());
+
+        // Action failure.
+        exception.expect(DOMActionException.class);
+        doReturn(FluentFutures.immediateFailedFluentFuture(new ClusteringActionException("mock")))
+            .when(mockDOMActionService).invokeAction(any(), any(), any());
+        try {
+            slaveDomActionService.invokeAction(schemaPath, domDataTreeIdentifier, outputNode).get(2, TimeUnit.SECONDS);
+        } catch (ExecutionException e) {
+            throw e.getCause();
+        }
+    }
+
     @Test
     public void testSlaveNewTransactionRequests() {
 
-        doReturn(mock(DOMDataReadOnlyTransaction.class)).when(mockDOMDataBroker).newReadOnlyTransaction();
-        doReturn(mock(DOMDataReadWriteTransaction.class)).when(mockDOMDataBroker).newReadWriteTransaction();
-        doReturn(mock(DOMDataWriteTransaction.class)).when(mockDOMDataBroker).newWriteOnlyTransaction();
+        doReturn(mock(DOMDataTreeReadTransaction.class)).when(mockDOMDataBroker).newReadOnlyTransaction();
+        doReturn(mock(DOMDataTreeReadWriteTransaction.class)).when(mockDOMDataBroker).newReadWriteTransaction();
+        doReturn(mock(DOMDataTreeWriteTransaction.class)).when(mockDOMDataBroker).newWriteOnlyTransaction();
 
         initializeMaster(Collections.emptyList());
         registerSlaveMountPoint();
@@ -522,12 +625,15 @@ public class NetconfNodeActorTest {
     }
 
     private ActorRef registerSlaveMountPoint() {
+        SchemaResourcesDTO schemaResourceDTO2 = mock(SchemaResourcesDTO.class);
+        doReturn(mockRegistry).when(schemaResourceDTO2).getSchemaRegistry();
+        doReturn(mockSchemaRepository).when(schemaResourceDTO2).getSchemaRepository();
         final ActorRef slaveRef = system.actorOf(NetconfNodeActor.props(
-                NetconfTopologySetupBuilder.create().setActorSystem(system).build(), remoteDeviceId, mockRegistry,
-                mockSchemaRepository, TIMEOUT, mockMountPointService));
+                NetconfTopologySetupBuilder.create().setSchemaResourceDTO(schemaResourceDTO2).setActorSystem(system)
+                .setBaseSchemas(BASE_SCHEMAS).build(), remoteDeviceId, TIMEOUT, mockMountPointService));
 
         doReturn(Futures.immediateFuture(mockSchemaContext))
-                .when(mockSchemaContextFactory).createSchemaContext(any());
+                .when(mockSchemaContextFactory).createEffectiveModelContext(anyCollection());
 
         slaveRef.tell(new RegisterMountPoint(ImmutableList.of(SOURCE_IDENTIFIER1, SOURCE_IDENTIFIER2),
                 masterRef), testKit.getRef());
@@ -543,9 +649,9 @@ public class NetconfNodeActorTest {
         return slaveRef;
     }
 
-    private void initializeMaster(List<SourceIdentifier> sourceIdentifiers) {
+    private void initializeMaster(final List<SourceIdentifier> sourceIdentifiers) {
         masterRef.tell(new CreateInitialMasterActorData(mockDOMDataBroker, sourceIdentifiers,
-                mockDOMRpcService), testKit.getRef());
+                mockDOMRpcService, mockDOMActionService), testKit.getRef());
 
         testKit.expectMsgClass(MasterActorDataInitialized.class);
     }
@@ -561,13 +667,7 @@ public class NetconfNodeActorTest {
     }
 
     private static PotentialSchemaSource<?> withSourceId(final SourceIdentifier identifier) {
-        return argThat(new ArgumentMatcher<PotentialSchemaSource<?>>() {
-            @Override
-            public boolean matches(final Object argument) {
-                final PotentialSchemaSource<?> potentialSchemaSource = (PotentialSchemaSource<?>) argument;
-                return identifier.equals(potentialSchemaSource.getSourceIdentifier());
-            }
-        });
+        return argThat(argument -> identifier.equals(argument.getSourceIdentifier()));
     }
 
     private static String convertStreamToString(final InputStream is) {