X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2Ftest%2FInvokeRpcMethodTest.java;h=b42178a9c6cfbc965c92957b5e28420d4764c4bf;hb=3b628b4074fb9bff60af58009c428eb9fbb10551;hp=d58b7e9dab0cecac48f4d5641dd2b6ff9bc8ba3a;hpb=43b37a609662f705d2dd701cb8b7c479144d2ef1;p=controller.git diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index d58b7e9dab..b42178a9c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -1,27 +1,65 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2014 Brocade Communications Systems, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import java.net.*; -import java.util.*; +import java.io.FileNotFoundException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; -import org.junit.*; +import javax.ws.rs.core.Response.Status; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.opendaylight.controller.sal.restconf.impl.*; -import org.opendaylight.yangtools.yang.common.*; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.controller.sal.core.api.mount.MountInstance; +import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; +import org.opendaylight.controller.sal.restconf.impl.ResponseException; +import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; +import org.opendaylight.controller.sal.restconf.impl.StructuredData; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +import com.google.common.util.concurrent.ListenableFuture; public class InvokeRpcMethodTest { - private static Set modules; + private RestconfImpl restconfImpl = null; + private static ControllerContext controllerContext = null; private class AnswerImpl implements Answer> { @Override @@ -32,11 +70,24 @@ public class InvokeRpcMethodTest { } @BeforeClass - public static void initialization() { - modules = TestUtils.resolveModules("/invoke-rpc"); - assertEquals(1, modules.size()); - Module module = TestUtils.resolveModule("invoke-rpc-module", modules); + public static void init() throws FileNotFoundException { + Set allModules = new HashSet( TestUtils + .loadModulesFrom("/full-versions/yangs") ); + allModules.addAll( TestUtils.loadModulesFrom("/invoke-rpc") ); + assertNotNull(allModules); + Module module = TestUtils.resolveModule("invoke-rpc-module", allModules); assertNotNull(module); + SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); + controllerContext = spy( ControllerContext.getInstance() ); + controllerContext.setSchemas(schemaContext); + + } + + @Before + public void initMethod() + { + restconfImpl = RestconfImpl.getInstance(); + restconfImpl.setControllerContext( controllerContext ); } /** @@ -46,11 +97,10 @@ public class InvokeRpcMethodTest { * from string - first argument). */ @Test - public void invokeRpcMethodTest() { - ControllerContext contContext = ControllerContext.getInstance(); - contContext.onGlobalContextUpdated(TestUtils.loadSchemaContext(modules)); + public void invokeRpcMtethodTest() { + ControllerContext contContext = controllerContext; try { - contContext.findModuleByNamespace(new URI("invoke:rpc:module")); + contContext.findModuleNameByNamespace(new URI("invoke:rpc:module")); } catch (URISyntaxException e) { assertTrue("Uri wasn't created sucessfuly", false); } @@ -64,21 +114,7 @@ public class InvokeRpcMethodTest { when(mockedBrokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenAnswer(new AnswerImpl()); StructuredData structData = restconf.invokeRpc("invoke-rpc-module:rpc-test", preparePayload()); - - CompositeNode rpcCompNode = structData.getData(); - CompositeNode cont = null; - assertEquals("invoke:rpc:module", rpcCompNode.getNodeType().getNamespace().toString()); - assertEquals("rpc-test", rpcCompNode.getNodeType().getLocalName()); - - for (Node node : rpcCompNode.getChildren()) { - if (node.getNodeType().getLocalName().equals("cont") - && node.getNodeType().getNamespace().toString().equals("nmspc")) { - if (node instanceof CompositeNode) { - cont = (CompositeNode) node; - } - } - } - assertNotNull(cont); + assertTrue(structData == null); } @@ -93,4 +129,198 @@ public class InvokeRpcMethodTest { return cont; } + @Test + public void testInvokeRpcWithNoPayloadRpc_FailNoErrors() { + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(false); + + ArgumentCaptor payload = ArgumentCaptor + .forClass(CompositeNode.class); + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when( + brokerFacade.invokeRpc( + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")), + payload.capture())).thenReturn(rpcResult); + + restconfImpl.setBroker(brokerFacade); + + try { + restconfImpl.invokeRpc("toaster:cancel-toast", ""); + fail("Expected an exception to be thrown."); + } catch (ResponseException e) { + assertEquals(e.getMessage(), + Status.INTERNAL_SERVER_ERROR.getStatusCode(), e + .getResponse().getStatus()); + } + } + + @Test + public void testInvokeRpcWithNoPayloadRpc_FailWithRpcError() { + List rpcErrors = new LinkedList(); + + RpcError unknownError = mock(RpcError.class); + when( unknownError.getTag() ).thenReturn( "bogusTag" ); + rpcErrors.add( unknownError ); + + RpcError knownError = mock( RpcError.class ); + when( knownError.getTag() ).thenReturn( "in-use" ); + rpcErrors.add( knownError ); + + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(false); + when(rpcResult.getErrors()).thenReturn( rpcErrors ); + + ArgumentCaptor payload = ArgumentCaptor + .forClass(CompositeNode.class); + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when( + brokerFacade.invokeRpc( + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")), + payload.capture())).thenReturn(rpcResult); + + restconfImpl.setBroker(brokerFacade); + + try { + restconfImpl.invokeRpc("toaster:cancel-toast", ""); + fail("Expected an exception to be thrown."); + } catch (ResponseException e) { + //TODO: Change to a 409 in the future - waiting on additional BUG to enhance this. + assertEquals(e.getMessage(), 500, e.getResponse().getStatus()); + } + } + + @Test + public void testInvokeRpcWithNoPayload_Success() { + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(true); + + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when( + brokerFacade.invokeRpc( + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")), + any( CompositeNode.class ))).thenReturn(rpcResult); + + restconfImpl.setBroker(brokerFacade); + + StructuredData output = restconfImpl.invokeRpc("toaster:cancel-toast", + ""); + assertEquals(null, output); + //additional validation in the fact that the restconfImpl does not throw an exception. + } + + @Test + public void testInvokeRpcMethodExpectingNoPayloadButProvidePayload() { + try { + restconfImpl.invokeRpc("toaster:cancel-toast", " a payload "); + fail("Expected an exception"); + } catch (ResponseException e) { + assertEquals(e.getMessage(), + Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode(), e + .getResponse().getStatus()); + } + } + + @Test + public void testInvokeRpcMethodWithBadMethodName() { + try { + restconfImpl.invokeRpc("toaster:bad-method", ""); + fail("Expected an exception"); + } catch (ResponseException e) { + assertEquals(e.getMessage(), Status.NOT_FOUND.getStatusCode(), e + .getResponse().getStatus()); + } + } + + @Test + public void testInvokeRpcMethodWithInput() { + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(true); + + CompositeNode payload = mock(CompositeNode.class); + + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when( + brokerFacade.invokeRpc( + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast")), + any(CompositeNode.class))).thenReturn(rpcResult); + + restconfImpl.setBroker(brokerFacade); + + StructuredData output = restconfImpl.invokeRpc("toaster:make-toast", + payload); + assertEquals(null, output); + //additional validation in the fact that the restconfImpl does not throw an exception. + } + + @Test + public void testThrowExceptionWhenSlashInModuleName() { + try { + restconfImpl.invokeRpc("toaster/slash", ""); + fail("Expected an exception."); + } catch (ResponseException e) { + assertEquals(e.getMessage(), Status.NOT_FOUND.getStatusCode(), e + .getResponse().getStatus()); + } + } + + @Test + public void testInvokeRpcWithNoPayloadWithOutput_Success() { + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(true); + + CompositeNode compositeNode = mock( CompositeNode.class ); + when( rpcResult.getResult() ).thenReturn( compositeNode ); + + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when( brokerFacade.invokeRpc( + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")), + any( CompositeNode.class ))).thenReturn(rpcResult); + + restconfImpl.setBroker(brokerFacade); + + StructuredData output = restconfImpl.invokeRpc("toaster:testOutput", + ""); + assertNotNull( output ); + assertSame( compositeNode, output.getData() ); + assertNotNull( output.getSchema() ); + } + + @Test + public void testMountedRpcCallNoPayload_Success() throws Exception + { + RpcResult rpcResult = mock(RpcResult.class); + when(rpcResult.isSuccessful()).thenReturn(true); + + ListenableFuture> mockListener = mock( ListenableFuture.class ); + when( mockListener.get() ).thenReturn( rpcResult ); + + QName cancelToastQName = QName.create( "cancelToast" ); + + RpcDefinition mockRpc = mock( RpcDefinition.class ); + when( mockRpc.getQName() ).thenReturn( cancelToastQName ); + + MountInstance mockMountPoint = mock( MountInstance.class ); + when( mockMountPoint.rpc( eq( cancelToastQName ), any( CompositeNode.class ) ) ) + .thenReturn( mockListener ); + + InstanceIdWithSchemaNode mockedInstanceId = mock( InstanceIdWithSchemaNode.class ); + when( mockedInstanceId.getMountPoint() ).thenReturn( mockMountPoint ); + + ControllerContext mockedContext = mock( ControllerContext.class ); + String cancelToastStr = "toaster:cancel-toast"; + when( mockedContext.urlPathArgDecode( cancelToastStr ) ).thenReturn( cancelToastStr ); + when( mockedContext.getRpcDefinition( cancelToastStr ) ).thenReturn( mockRpc ); + when( mockedContext.toMountPointIdentifier( "opendaylight-inventory:nodes/node/" + + "REMOTE_HOST/yang-ext:mount/toaster:cancel-toast" ) ).thenReturn( mockedInstanceId ); + + restconfImpl.setControllerContext( mockedContext ); + StructuredData output = restconfImpl.invokeRpc( + "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", + ""); + assertEquals(null, output); + + //additional validation in the fact that the restconfImpl does not throw an exception. + } + + }