Unit test for RestconfInvokeOperationsUtil class 61/44661/8
authormiroslav.kovac <miroslav.kovac@pantheon.tech>
Wed, 24 Aug 2016 13:34:43 +0000 (15:34 +0200)
committerMiroslav Kovac <miroslav.kovac@pantheon.tech>
Mon, 5 Sep 2016 09:00:35 +0000 (09:00 +0000)
Fixed so it add rpcError to the result when there is one.

Change-Id: I5e3e924a0e80970f2f754e2ec39d58e4b0a06984
Signed-off-by: miroslav.kovac <miroslav.kovac@pantheon.tech>
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/FutureCallbackTx.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/RestconfInvokeOperationsUtil.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/RestconfInvokeOperationsUtilTest.java [new file with mode: 0644]
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/TestData.java

index a4dbe6fa23d420012a563578d66953801abf06df..01760376b95ba9c037685f3a99deb34f78044568 100644 (file)
@@ -10,9 +10,15 @@ package org.opendaylight.restconf.restful.utils;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,7 +52,7 @@ final class FutureCallbackTx {
             @Override
             public void onFailure(final Throwable t) {
                 responseWaiter.countDown();
-                handlingLoggerAndValues(t, txType, null, null);
+                handlingLoggerAndValues(t, txType, null, dataFactory);
             }
 
             @Override
@@ -85,7 +91,13 @@ final class FutureCallbackTx {
             final T result, final FutureDataFactory<T> dataFactory) {
         if (t != null) {
             LOG.warn("Transaction({}) FAILED!", txType, t);
-            throw new RestconfDocumentedException("  Transaction(" + txType + ") not committed correctly", t);
+            if (t instanceof DOMRpcException) {
+                final List<RpcError> rpcErrorList = new ArrayList<>();
+                rpcErrorList.add(RpcResultBuilder.newError(RpcError.ErrorType.RPC, "operation-failed", t.getMessage()));
+                dataFactory.setResult((T) new DefaultDOMRpcResult(rpcErrorList));
+            } else {
+                throw new RestconfDocumentedException("  Transaction(" + txType + ") not committed correctly", t);
+            }
         } else {
             LOG.trace("Transaction({}) SUCCESSFUL!", txType);
             dataFactory.setResult(result);
index 39f5890043518634f9ee32edb28f922dd4bfbf2d..023e70dd53458af384810bccca7732500875cc53 100644 (file)
@@ -94,7 +94,7 @@ public class RestconfInvokeOperationsUtil {
             return null;
         }
         try {
-            if ((response.getErrors() == null) || response.getErrors().isEmpty()) {
+            if (response.getErrors().isEmpty()) {
                 return response;
             }
             LOG.debug("RpcError message", response.getErrors());
diff --git a/restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/RestconfInvokeOperationsUtilTest.java b/restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/RestconfInvokeOperationsUtilTest.java
new file mode 100644 (file)
index 0000000..7935895
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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.restful.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+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.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.restconf.handlers.RpcServiceHandler;
+import org.opendaylight.yangtools.yang.common.RpcError;
+
+public class RestconfInvokeOperationsUtilTest {
+
+    private static final TestData data = new TestData();
+
+    private RpcServiceHandler serviceHandler;
+    @Mock
+    private DOMRpcService rpcService;
+    @Mock
+    private DOMMountPoint moutPoint;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        serviceHandler = new RpcServiceHandler(rpcService);
+    }
+
+    @Test
+    public void invokeRpcTest() {
+        final DOMRpcResult mockResult = new DefaultDOMRpcResult(data.output, Collections.emptyList());
+        doReturn(Futures.immediateCheckedFuture(mockResult)).when(rpcService).invokeRpc(data.rpc, data.input);
+        final DOMRpcResult rpcResult = RestconfInvokeOperationsUtil.invokeRpc(data.input, data.rpc, serviceHandler);
+        Assert.assertTrue(rpcResult.getErrors().isEmpty());
+        assertEquals(data.output, rpcResult.getResult());
+    }
+
+    @Test(expected = RestconfDocumentedException.class)
+    public void invokeRpcErrorsAndCheckTestTest() {
+        final DOMRpcException exception = new DOMRpcImplementationNotAvailableException("No implementation of RPC " + data.errorRpc.toString() + " availible");
+        doReturn(Futures.immediateFailedCheckedFuture(exception)).when(rpcService).invokeRpc(data.errorRpc, data.input);
+        final DOMRpcResult rpcResult = RestconfInvokeOperationsUtil.invokeRpc(data.input, data.errorRpc, serviceHandler);
+        assertNull(rpcResult.getResult());
+        final Collection<RpcError> errorList = rpcResult.getErrors();
+        assertEquals(1, errorList.size());
+        final RpcError actual = errorList.iterator().next();
+        assertEquals("No implementation of RPC " + data.errorRpc.toString() + " availible", actual.getMessage());
+        assertEquals("operation-failed", actual.getTag());
+        assertEquals(RpcError.ErrorType.RPC, actual.getErrorType());
+        RestconfInvokeOperationsUtil.checkResponse(rpcResult);
+    }
+
+    @Test
+    public void invokeRpcViaMountPointTest() {
+        doReturn(Optional.fromNullable(rpcService)).when(moutPoint).getService(DOMRpcService.class);
+        final DOMRpcResult mockResult = new DefaultDOMRpcResult(data.output, Collections.emptyList());
+        doReturn(Futures.immediateCheckedFuture(mockResult)).when(rpcService).invokeRpc(data.rpc, data.input);
+        final DOMRpcResult rpcResult = RestconfInvokeOperationsUtil.invokeRpcViaMountPoint(moutPoint, data.input, data.rpc);
+        Assert.assertTrue(rpcResult.getErrors().isEmpty());
+        assertEquals(data.output, rpcResult.getResult());
+    }
+
+    @Test(expected = RestconfDocumentedException.class)
+    public void invokeRpcMissingMountPointServiceTest() {
+        doReturn(Optional.absent()).when(moutPoint).getService(DOMRpcService.class);
+        final DOMRpcResult mockResult = new DefaultDOMRpcResult(data.output, Collections.emptyList());
+        doReturn(Futures.immediateCheckedFuture(mockResult)).when(rpcService).invokeRpc(data.rpc, data.input);
+        final DOMRpcResult rpcResult = RestconfInvokeOperationsUtil.invokeRpcViaMountPoint(moutPoint, data.input, data.rpc);
+    }
+
+    @Test
+    public void checkResponseTest() {
+        final DOMRpcResult mockResult = new DefaultDOMRpcResult(data.output, Collections.emptyList());
+        doReturn(Futures.immediateCheckedFuture(mockResult)).when(rpcService).invokeRpc(data.rpc, data.input);
+        final DOMRpcResult rpcResult = RestconfInvokeOperationsUtil.invokeRpc(data.input, data.rpc, serviceHandler);
+        Assert.assertTrue(rpcResult.getErrors().isEmpty());
+        assertEquals(data.output, rpcResult.getResult());
+        assertNotNull(RestconfInvokeOperationsUtil.checkResponse(rpcResult));
+    }
+
+}
index 19728442e4ed21dedf9cbe3222eed178498e62d4..265acea3ebcc47933fc14c4965cf727cd487c3c0 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
 class TestData {
 
@@ -32,6 +33,10 @@ class TestData {
     final LeafNode contentLeaf;
     final LeafNode contentLeaf2;
     final MapEntryNode checkData;
+    final SchemaPath rpc;
+    final SchemaPath errorRpc;
+    final ContainerNode input;
+    final ContainerNode output;
 
     TestData() {
         final QName base = QName.create("ns", "2016-02-28", "base");
@@ -109,5 +114,27 @@ class TestData {
                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(base, "container2")))
                 .withChild(contentLeaf2)
                 .build();
+
+
+        final QName rpcQname = QName.create("ns", "2015-02-28", "test-rpc");
+        final QName errorRpcQname = QName.create(rpcQname, "error-rpc");
+        rpc = SchemaPath.create(true, rpcQname);
+        errorRpc = SchemaPath.create(true, errorRpcQname);
+        final LeafNode contentLeafNode = Builders.leafBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(rpcQname, "content")))
+                .withValue("test")
+                .build();
+        input = Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(rpcQname, "input")))
+                .withChild(contentLeafNode)
+                .build();
+        final LeafNode resultLeafNode = Builders.leafBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(rpcQname, "content")))
+                .withValue("operation result")
+                .build();
+        output = Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(rpcQname, "output")))
+                .withChild(resultLeafNode)
+                .build();
     }
 }
\ No newline at end of file